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
This commit is contained in:
clayjohn 2022-11-13 12:46:52 -08:00
parent b05e1e7d69
commit 4abf47f407
9 changed files with 47 additions and 14 deletions

View file

@ -529,13 +529,13 @@
The material will use the texture's alpha values for transparency.
</constant>
<constant name="TRANSPARENCY_ALPHA_SCISSOR" value="2" enum="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.
</constant>
<constant name="TRANSPARENCY_ALPHA_HASH" value="3" enum="Transparency">
The material will cut off all values below a spatially-deterministic threshold, the rest will remain opaque.
</constant>
<constant name="TRANSPARENCY_ALPHA_DEPTH_PRE_PASS" value="4" enum="Transparency">
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.
</constant>
<constant name="TRANSPARENCY_MAX" value="5" enum="Transparency">
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.
</constant>
<constant name="DEPTH_DRAW_OPAQUE_ONLY" value="0" enum="DepthDrawMode">
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.
</constant>
<constant name="DEPTH_DRAW_ALWAYS" value="1" enum="DepthDrawMode">
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].
</constant>
<constant name="DEPTH_DRAW_DISABLED" value="2" enum="DepthDrawMode">
No depth draw.
Objects will not write their depth to the depth buffer, even during the depth prepass (if enabled).
</constant>
<constant name="CULL_BACK" value="0" enum="CullMode">
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.
</constant>
<constant name="FLAG_DISABLE_DEPTH_TEST" value="0" enum="Flags">
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.
</constant>
<constant name="FLAG_ALBEDO_FROM_VERTEX_COLOR" value="1" enum="Flags">
Set [code]ALBEDO[/code] to the per-vertex color specified in the mesh.

View file

@ -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 {

View file

@ -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;

View file

@ -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;

View file

@ -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 {

View file

@ -150,8 +150,8 @@ public:
String code;
HashMap<StringName, HashMap<int, RID>> 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;

View file

@ -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;

View file

@ -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 {

View file

@ -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;