From 4abf47f407d45289c4900e3025013f452f563c86 Mon Sep 17 00:00:00 2001 From: clayjohn Date: Sun, 13 Nov 2022 12:46:52 -0800 Subject: [PATCH] Implement is_animated and casts_shadows This allows the renderer to correctly decide when to update shadow maps This PR also adds TIME to a few missing places --- doc/classes/BaseMaterial3D.xml | 13 +++++++------ drivers/gles3/storage/material_storage.cpp | 10 ++++++++-- drivers/gles3/storage/material_storage.h | 2 ++ .../forward_clustered/render_forward_clustered.cpp | 4 ++++ .../scene_shader_forward_clustered.cpp | 10 ++++++++-- .../scene_shader_forward_clustered.h | 6 ++++-- .../forward_mobile/render_forward_mobile.cpp | 4 ++++ .../forward_mobile/scene_shader_forward_mobile.cpp | 10 ++++++++-- .../forward_mobile/scene_shader_forward_mobile.h | 2 ++ 9 files changed, 47 insertions(+), 14 deletions(-) diff --git a/doc/classes/BaseMaterial3D.xml b/doc/classes/BaseMaterial3D.xml index de980eab0c5..fbb31cadcdf 100644 --- a/doc/classes/BaseMaterial3D.xml +++ b/doc/classes/BaseMaterial3D.xml @@ -529,13 +529,13 @@ The material will use the texture's alpha values for transparency. - The material will cut off all values below a threshold, the rest will remain opaque. + The material will cut off all values below a threshold, the rest will remain opaque. The opaque portions will be rendering in the depth prepass. The material will cut off all values below a spatially-deterministic threshold, the rest will remain opaque. - The material will use the texture's alpha value for transparency, but will still be rendered in the pre-pass. + The material will use the texture's alpha value for transparency, but will still be rendered in the depth prepass. Represents the size of the [enum Transparency] enum. @@ -613,13 +613,14 @@ Enables AlphaToCoverage and forces all non-zero alpha values to [code]1[/code]. Alpha values in the material are passed to the AntiAliasing sample mask. - Default depth draw mode. Depth is drawn only for opaque objects. + Default depth draw mode. Depth is drawn only for opaque objects during the opaque prepass (if any) and during the opaque pass. - Depth draw is calculated for both opaque and transparent objects. + Objects will write to depth during the opaque and the transparent passes. Transparent objects that are close to the camera may obscure other transparent objects behind them. + [b]Note:[/b] This does not influence whether transparent objects are included in the depth prepass or not. For that, see [enum Transparency]. - No depth draw. + Objects will not write their depth to the depth buffer, even during the depth prepass (if enabled). Default cull mode. The back of the object is culled when not visible. Back face triangles will be culled when facing the camera. This results in only the front side of triangles being drawn. For closed-surface meshes this means that only the exterior of the mesh will be visible. @@ -631,7 +632,7 @@ No culling is performed. - Disables the depth test, so this object is drawn on top of all others. However, objects drawn after it in the draw order may cover it. + Disables the depth test, so this object is drawn on top of all others drawn before it. This puts the object in the transparent draw pass where it is sorted based on distance to camera. Objects drawn after it in the draw order may cover it. This also disables writing to depth. Set [code]ALBEDO[/code] to the per-vertex color specified in the mesh. diff --git a/drivers/gles3/storage/material_storage.cpp b/drivers/gles3/storage/material_storage.cpp index 6748eb3676e..3ea61e252b3 100644 --- a/drivers/gles3/storage/material_storage.cpp +++ b/drivers/gles3/storage/material_storage.cpp @@ -3418,6 +3418,8 @@ void SceneShaderData::set_code(const String &p_code) { vertex_input_mask |= uses_bones << 9; vertex_input_mask |= uses_weights << 10; uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; + uses_vertex_time = gen_code.uses_vertex_time; + uses_fragment_time = gen_code.uses_fragment_time; #if 0 print_line("**compiling shader:"); @@ -3538,11 +3540,15 @@ bool SceneShaderData::is_parameter_texture(const StringName &p_param) const { } bool SceneShaderData::is_animated() const { - return false; + return (uses_fragment_time && uses_discard) || (uses_vertex_time && uses_vertex); } bool SceneShaderData::casts_shadows() const { - return false; + bool has_read_screen_alpha = uses_screen_texture || uses_depth_texture || uses_normal_texture; + bool has_base_alpha = (uses_alpha && !uses_alpha_clip) || has_read_screen_alpha; + bool has_alpha = has_base_alpha || uses_blend_alpha; + + return !has_alpha || (uses_depth_pre_pass && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test == DEPTH_TEST_DISABLED)); } Variant SceneShaderData::get_default_parameter(const StringName &p_parameter) const { diff --git a/drivers/gles3/storage/material_storage.h b/drivers/gles3/storage/material_storage.h index 24d9a0fee1f..9ebfc3097c0 100644 --- a/drivers/gles3/storage/material_storage.h +++ b/drivers/gles3/storage/material_storage.h @@ -318,6 +318,8 @@ struct SceneShaderData : public ShaderData { bool uses_depth_texture; bool uses_normal_texture; bool uses_time; + bool uses_vertex_time; + bool uses_fragment_time; bool writes_modelview_or_projection; bool uses_world_coordinates; bool uses_tangent; diff --git a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp index 86425512b88..d6dd56c9590 100644 --- a/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/render_forward_clustered.cpp @@ -2403,6 +2403,8 @@ void RenderForwardClustered::_render_particle_collider_heightfield(RID p_fb, con scene_data.z_far = p_cam_projection.get_z_far(); scene_data.dual_paraboloid_side = 0; scene_data.opaque_prepass_threshold = 0.0; + scene_data.time = time; + scene_data.time_step = time_step; RenderDataRD render_data; render_data.scene_data = &scene_data; @@ -2445,6 +2447,8 @@ void RenderForwardClustered::_render_material(const Transform3D &p_cam_transform scene_data.material_uv2_mode = false; scene_data.opaque_prepass_threshold = 0.0f; scene_data.emissive_exposure_normalization = p_exposure_normalization; + scene_data.time = time; + scene_data.time_step = time_step; RenderDataRD render_data; render_data.scene_data = &scene_data; diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp index c1b23af82f9..d2f66896d7a 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.cpp @@ -151,6 +151,8 @@ void SceneShaderForwardClustered::ShaderData::set_code(const String &p_code) { depth_test = DepthTest(depth_testi); cull_mode = Cull(cull_modei); uses_screen_texture_mipmaps = gen_code.uses_screen_texture_mipmaps; + uses_vertex_time = gen_code.uses_vertex_time; + uses_fragment_time = gen_code.uses_fragment_time; #if 0 print_line("**compiling shader:"); @@ -457,11 +459,15 @@ bool SceneShaderForwardClustered::ShaderData::is_parameter_texture(const StringN } bool SceneShaderForwardClustered::ShaderData::is_animated() const { - return false; + return (uses_fragment_time && uses_discard) || (uses_vertex_time && uses_vertex); } bool SceneShaderForwardClustered::ShaderData::casts_shadows() const { - return false; + bool has_read_screen_alpha = uses_screen_texture || uses_depth_texture || uses_normal_texture; + bool has_base_alpha = (uses_alpha && !uses_alpha_clip) || has_read_screen_alpha; + bool has_alpha = has_base_alpha || uses_blend_alpha; + + return !has_alpha || (uses_depth_pre_pass && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test == DEPTH_TEST_DISABLED)); } Variant SceneShaderForwardClustered::ShaderData::get_default_parameter(const StringName &p_parameter) const { diff --git a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h index a9a9fa94de6..194edf2dcbb 100644 --- a/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h +++ b/servers/rendering/renderer_rd/forward_clustered/scene_shader_forward_clustered.h @@ -150,8 +150,8 @@ public: String code; HashMap> default_texture_params; - DepthDraw depth_draw; - DepthTest depth_test; + DepthDraw depth_draw = DEPTH_DRAW_OPAQUE; + DepthTest depth_test = DEPTH_TEST_ENABLED; bool uses_point_size = false; bool uses_alpha = false; @@ -172,6 +172,8 @@ public: bool uses_depth_texture = false; bool uses_normal_texture = false; bool uses_time = false; + bool uses_vertex_time = false; + bool uses_fragment_time = false; bool writes_modelview_or_projection = false; bool uses_world_coordinates = false; bool uses_screen_texture_mipmaps = false; diff --git a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp index 16711b0d5d3..558aba62e12 100644 --- a/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/render_forward_mobile.cpp @@ -1363,6 +1363,8 @@ void RenderForwardMobile::_render_material(const Transform3D &p_cam_transform, c scene_data.material_uv2_mode = false; scene_data.opaque_prepass_threshold = 0.0f; scene_data.emissive_exposure_normalization = p_exposure_normalization; + scene_data.time = time; + scene_data.time_step = time_step; RenderDataRD render_data; render_data.scene_data = &scene_data; @@ -1486,6 +1488,8 @@ void RenderForwardMobile::_render_particle_collider_heightfield(RID p_fb, const scene_data.z_far = p_cam_projection.get_z_far(); scene_data.dual_paraboloid_side = 0; scene_data.opaque_prepass_threshold = 0.0; + scene_data.time = time; + scene_data.time_step = time_step; RenderDataRD render_data; render_data.scene_data = &scene_data; diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp index 02bd30d32dc..7ed6e24cf48 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.cpp @@ -150,6 +150,8 @@ void SceneShaderForwardMobile::ShaderData::set_code(const String &p_code) { depth_draw = DepthDraw(depth_drawi); depth_test = DepthTest(depth_testi); + uses_vertex_time = gen_code.uses_vertex_time; + uses_fragment_time = gen_code.uses_fragment_time; #if 0 print_line("**compiling shader:"); @@ -412,11 +414,15 @@ bool SceneShaderForwardMobile::ShaderData::is_parameter_texture(const StringName } bool SceneShaderForwardMobile::ShaderData::is_animated() const { - return false; + return (uses_fragment_time && uses_discard) || (uses_vertex_time && uses_vertex); } bool SceneShaderForwardMobile::ShaderData::casts_shadows() const { - return false; + bool has_read_screen_alpha = uses_screen_texture || uses_depth_texture || uses_normal_texture; + bool has_base_alpha = (uses_alpha && !uses_alpha_clip) || has_read_screen_alpha; + bool has_alpha = has_base_alpha || uses_blend_alpha; + + return !has_alpha || (uses_depth_pre_pass && !(depth_draw == DEPTH_DRAW_DISABLED || depth_test == DEPTH_TEST_DISABLED)); } Variant SceneShaderForwardMobile::ShaderData::get_default_parameter(const StringName &p_parameter) const { diff --git a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h index f67665a02fd..5b51cfc8c3c 100644 --- a/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h +++ b/servers/rendering/renderer_rd/forward_mobile/scene_shader_forward_mobile.h @@ -132,6 +132,8 @@ public: bool uses_depth_texture = false; bool uses_normal_texture = false; bool uses_time = false; + bool uses_vertex_time = false; + bool uses_fragment_time = false; bool writes_modelview_or_projection = false; bool uses_world_coordinates = false;