@ -969,6 +969,13 @@ void RendererSceneCull::instance_geometry_set_lightmap(RID p_instance, RID p_lig
}
}
void RendererSceneCull : : instance_geometry_set_lod_bias ( RID p_instance , float p_lod_bias ) {
Instance * instance = instance_owner . getornull ( p_instance ) ;
ERR_FAIL_COND ( ! instance ) ;
instance - > lod_bias = p_lod_bias ;
}
void RendererSceneCull : : instance_geometry_set_shader_parameter ( RID p_instance , const StringName & p_parameter , const Variant & p_value ) {
Instance * instance = instance_owner . getornull ( p_instance ) ;
ERR_FAIL_COND ( ! instance ) ;
@ -1325,7 +1332,7 @@ void RendererSceneCull::_update_instance_lightmap_captures(Instance *p_instance)
}
}
bool RendererSceneCull : : _light_instance_update_shadow ( Instance * p_instance , const Transform p_cam_transform , const CameraMatrix & p_cam_projection , bool p_cam_orthogonal , bool p_cam_vaspect , RID p_shadow_atlas , Scenario * p_scenario ) {
bool RendererSceneCull : : _light_instance_update_shadow ( Instance * p_instance , const Transform p_cam_transform , const CameraMatrix & p_cam_projection , bool p_cam_orthogonal , bool p_cam_vaspect , RID p_shadow_atlas , Scenario * p_scenario , float p_screen_lod_threshold ) {
InstanceLightData * light = static_cast < InstanceLightData * > ( p_instance - > base_data ) ;
Transform light_transform = p_instance - > transform ;
@ -1335,6 +1342,8 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
switch ( RSG : : storage - > light_get_type ( p_instance - > base ) ) {
case RS : : LIGHT_DIRECTIONAL : {
Plane camera_plane ( p_cam_transform . get_origin ( ) , - p_cam_transform . basis . get_axis ( Vector3 : : AXIS_Z ) ) ;
real_t max_distance = p_cam_projection . get_z_far ( ) ;
real_t shadow_max = RSG : : storage - > light_get_param ( p_instance - > base , RS : : LIGHT_PARAM_SHADOW_MAX_DISTANCE ) ;
if ( shadow_max > 0 & & ! p_cam_orthogonal ) { //its impractical (and leads to unwanted behaviors) to set max distance in orthogonal camera
@ -1703,7 +1712,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
RSG : : storage - > update_mesh_instances ( ) ;
scene_render - > render_shadow ( light - > instance , p_shadow_atlas , i , ( RendererSceneRender : : InstanceBase * * ) instance_shadow_cull_result , cull_count );
scene_render - > render_shadow ( light - > instance , p_shadow_atlas , i , ( RendererSceneRender : : InstanceBase * * ) instance_shadow_cull_result , cull_count , camera_plane , p_cam_projection . get_lod_multiplier ( ) , p_screen_lod_threshold );
}
} break ;
@ -1860,7 +1869,7 @@ bool RendererSceneCull::_light_instance_update_shadow(Instance *p_instance, cons
return animated_material_found ;
}
void RendererSceneCull : : render_camera ( RID p_render_buffers , RID p_camera , RID p_scenario , Size2 p_viewport_size , RID p_shadow_atlas ) {
void RendererSceneCull : : render_camera ( RID p_render_buffers , RID p_camera , RID p_scenario , Size2 p_viewport_size , float p_screen_lod_threshold , RID p_shadow_atlas ) {
// render to mono camera
# ifndef _3D_DISABLED
@ -1905,12 +1914,12 @@ void RendererSceneCull::render_camera(RID p_render_buffers, RID p_camera, RID p_
RID environment = _render_get_environment ( p_camera , p_scenario ) ;
_prepare_scene ( camera - > transform , camera_matrix , ortho , camera - > vaspect , p_render_buffers , environment , camera - > visible_layers , p_scenario , p_shadow_atlas , RID ( ) );
_render_scene ( p_render_buffers , camera - > transform , camera_matrix , ortho , environment , camera - > effects , p_scenario , p_shadow_atlas , RID ( ) , - 1 );
_prepare_scene ( camera - > transform , camera_matrix , ortho , camera - > vaspect , p_render_buffers , environment , camera - > visible_layers , p_scenario , p_shadow_atlas , RID ( ) , p_screen_lod_threshold );
_render_scene ( p_render_buffers , camera - > transform , camera_matrix , ortho , environment , camera - > effects , p_scenario , p_shadow_atlas , RID ( ) , - 1 , p_screen_lod_threshold );
# endif
}
void RendererSceneCull : : render_camera ( RID p_render_buffers , Ref < XRInterface > & p_interface , XRInterface : : Eyes p_eye , RID p_camera , RID p_scenario , Size2 p_viewport_size , RID p_shadow_atlas ) {
void RendererSceneCull : : render_camera ( RID p_render_buffers , Ref < XRInterface > & p_interface , XRInterface : : Eyes p_eye , RID p_camera , RID p_scenario , Size2 p_viewport_size , float p_screen_lod_threshold , RID p_shadow_atlas ) {
// render for AR/VR interface
Camera * camera = camera_owner . getornull ( p_camera ) ;
@ -1984,17 +1993,17 @@ void RendererSceneCull::render_camera(RID p_render_buffers, Ref<XRInterface> &p_
mono_transform * = apply_z_shift ;
// now prepare our scene with our adjusted transform projection matrix
_prepare_scene ( mono_transform , combined_matrix , false , false , p_render_buffers , environment , camera - > visible_layers , p_scenario , p_shadow_atlas , RID ( ) );
_prepare_scene ( mono_transform , combined_matrix , false , false , p_render_buffers , environment , camera - > visible_layers , p_scenario , p_shadow_atlas , RID ( ) , p_screen_lod_threshold );
} else if ( p_eye = = XRInterface : : EYE_MONO ) {
// For mono render, prepare as per usual
_prepare_scene ( cam_transform , camera_matrix , false , false , p_render_buffers , environment , camera - > visible_layers , p_scenario , p_shadow_atlas , RID ( ) );
_prepare_scene ( cam_transform , camera_matrix , false , false , p_render_buffers , environment , camera - > visible_layers , p_scenario , p_shadow_atlas , RID ( ) , p_screen_lod_threshold );
}
// And render our scene...
_render_scene ( p_render_buffers , cam_transform , camera_matrix , false , environment , camera - > effects , p_scenario , p_shadow_atlas , RID ( ) , - 1 );
_render_scene ( p_render_buffers , cam_transform , camera_matrix , false , environment , camera - > effects , p_scenario , p_shadow_atlas , RID ( ) , - 1 , p_screen_lod_threshold );
} ;
void RendererSceneCull : : _prepare_scene ( const Transform p_cam_transform , const CameraMatrix & p_cam_projection , bool p_cam_orthogonal , bool p_cam_vaspect , RID p_render_buffers , RID p_environment , uint32_t p_visible_layers , RID p_scenario , RID p_shadow_atlas , RID p_reflection_probe , bool p_using_shadows ) {
void RendererSceneCull : : _prepare_scene ( const Transform p_cam_transform , const CameraMatrix & p_cam_projection , bool p_cam_orthogonal , bool p_cam_vaspect , RID p_render_buffers , RID p_environment , uint32_t p_visible_layers , RID p_scenario , RID p_shadow_atlas , RID p_reflection_probe , float p_screen_lod_threshold , bool p_using_shadows ) {
// Note, in stereo rendering:
// - p_cam_transform will be a transform in the middle of our two eyes
// - p_cam_projection is a wider frustrum that encompasses both eyes
@ -2250,7 +2259,7 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
for ( int i = 0 ; i < directional_shadow_count ; i + + ) {
RENDER_TIMESTAMP ( " >Rendering Directional Light " + itos ( i ) ) ;
_light_instance_update_shadow ( lights_with_shadow [ i ] , p_cam_transform , p_cam_projection , p_cam_orthogonal , p_cam_vaspect , p_shadow_atlas , scenario );
_light_instance_update_shadow ( lights_with_shadow [ i ] , p_cam_transform , p_cam_projection , p_cam_orthogonal , p_cam_vaspect , p_shadow_atlas , scenario , p_screen_lod_threshold );
RENDER_TIMESTAMP ( " <Rendering Directional Light " + itos ( i ) ) ;
}
@ -2349,7 +2358,7 @@ void RendererSceneCull::_prepare_scene(const Transform p_cam_transform, const Ca
if ( redraw ) {
//must redraw!
RENDER_TIMESTAMP ( " >Rendering Light " + itos ( i ) ) ;
light - > shadow_dirty = _light_instance_update_shadow ( ins , p_cam_transform , p_cam_projection , p_cam_orthogonal , p_cam_vaspect , p_shadow_atlas , scenario );
light - > shadow_dirty = _light_instance_update_shadow ( ins , p_cam_transform , p_cam_projection , p_cam_orthogonal , p_cam_vaspect , p_shadow_atlas , scenario , p_screen_lod_threshold );
RENDER_TIMESTAMP ( " <Rendering Light " + itos ( i ) ) ;
}
}
@ -2447,7 +2456,7 @@ RID RendererSceneCull::_render_get_environment(RID p_camera, RID p_scenario) {
return RID ( ) ;
}
void RendererSceneCull : : _render_scene ( RID p_render_buffers , const Transform p_cam_transform , const CameraMatrix & p_cam_projection , bool p_cam_orthogonal , RID p_environment , RID p_force_camera_effects , RID p_scenario , RID p_shadow_atlas , RID p_reflection_probe , int p_reflection_probe_pass ) {
void RendererSceneCull : : _render_scene ( RID p_render_buffers , const Transform p_cam_transform , const CameraMatrix & p_cam_projection , bool p_cam_orthogonal , RID p_environment , RID p_force_camera_effects , RID p_scenario , RID p_shadow_atlas , RID p_reflection_probe , int p_reflection_probe_pass , float p_screen_lod_threshold ) {
Scenario * scenario = scenario_owner . getornull ( p_scenario ) ;
RID camera_effects ;
@ -2459,7 +2468,7 @@ void RendererSceneCull::_render_scene(RID p_render_buffers, const Transform p_ca
/* PROCESS GEOMETRY AND DRAW SCENE */
RENDER_TIMESTAMP ( " Render Scene " ) ;
scene_render - > render_scene ( p_render_buffers , p_cam_transform , p_cam_projection , p_cam_orthogonal , ( RendererSceneRender : : InstanceBase * * ) instance_cull_result , instance_cull_count , light_instance_cull_result , light_cull_count + directional_light_count , reflection_probe_instance_cull_result , reflection_probe_cull_count , gi_probe_instance_cull_result , gi_probe_cull_count , decal_instance_cull_result , decal_cull_count , ( RendererSceneRender : : InstanceBase * * ) lightmap_cull_result , lightmap_cull_count , p_environment , camera_effects , p_shadow_atlas , p_reflection_probe . is_valid ( ) ? RID ( ) : scenario - > reflection_atlas , p_reflection_probe , p_reflection_probe_pass );
scene_render - > render_scene ( p_render_buffers , p_cam_transform , p_cam_projection , p_cam_orthogonal , ( RendererSceneRender : : InstanceBase * * ) instance_cull_result , instance_cull_count , light_instance_cull_result , light_cull_count + directional_light_count , reflection_probe_instance_cull_result , reflection_probe_cull_count , gi_probe_instance_cull_result , gi_probe_cull_count , decal_instance_cull_result , decal_cull_count , ( RendererSceneRender : : InstanceBase * * ) lightmap_cull_result , lightmap_cull_count , p_environment , camera_effects , p_shadow_atlas , p_reflection_probe . is_valid ( ) ? RID ( ) : scenario - > reflection_atlas , p_reflection_probe , p_reflection_probe_pass , p_screen_lod_threshold );
}
void RendererSceneCull : : render_empty_scene ( RID p_render_buffers , RID p_scenario , RID p_shadow_atlas ) {
@ -2474,7 +2483,7 @@ void RendererSceneCull::render_empty_scene(RID p_render_buffers, RID p_scenario,
environment = scenario - > fallback_environment ;
}
RENDER_TIMESTAMP ( " Render Empty Scene " ) ;
scene_render - > render_scene ( p_render_buffers , Transform ( ) , CameraMatrix ( ) , true , nullptr , 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 , environment , RID ( ) , p_shadow_atlas , scenario - > reflection_atlas , RID ( ) , 0 );
scene_render - > render_scene ( p_render_buffers , Transform ( ) , CameraMatrix ( ) , true , nullptr , 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 , nullptr , 0 , environment , RID ( ) , p_shadow_atlas , scenario - > reflection_atlas , RID ( ) , 0 , 0 );
# endif
}
@ -2512,6 +2521,8 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
Vector3 extents = RSG : : storage - > reflection_probe_get_extents ( p_instance - > base ) ;
Vector3 origin_offset = RSG : : storage - > reflection_probe_get_origin_offset ( p_instance - > base ) ;
float max_distance = RSG : : storage - > reflection_probe_get_origin_max_distance ( p_instance - > base ) ;
float size = scene_render - > reflection_atlas_get_size ( scenario - > reflection_atlas ) ;
float lod_threshold = RSG : : storage - > reflection_probe_get_lod_threshold ( p_instance - > base ) / size ;
Vector3 edge = view_normals [ p_step ] * extents ;
float distance = ABS ( view_normals [ p_step ] . dot ( edge ) - view_normals [ p_step ] . dot ( origin_offset ) ) ; //distance from origin offset to actual view distance limit
@ -2535,8 +2546,8 @@ bool RendererSceneCull::_render_reflection_probe_step(Instance *p_instance, int
}
RENDER_TIMESTAMP ( " Render Reflection Probe, Step " + itos ( p_step ) ) ;
_prepare_scene ( xform , cm , false , false , RID ( ) , RID ( ) , RSG : : storage - > reflection_probe_get_cull_mask ( p_instance - > base ) , p_instance - > scenario - > self , shadow_atlas , reflection_probe - > instance , use_shadows) ;
_render_scene ( RID ( ) , xform , cm , false , RID ( ) , RID ( ) , p_instance - > scenario - > self , shadow_atlas , reflection_probe - > instance , p_step );
_prepare_scene ( xform , cm , false , false , RID ( ) , RID ( ) , RSG : : storage - > reflection_probe_get_cull_mask ( p_instance - > base ) , p_instance - > scenario - > self , shadow_atlas , reflection_probe - > instance , lod_threshold, use_shadows) ;
_render_scene ( RID ( ) , xform , cm , false , RID ( ) , RID ( ) , p_instance - > scenario - > self , shadow_atlas , reflection_probe - > instance , p_step , lod_threshold );
} else {
//do roughness postprocess step until it believes it's done