From cfcbc3111192e3719b4a15f4c32ac72bd9739710 Mon Sep 17 00:00:00 2001 From: Ansraer Date: Fri, 31 Mar 2023 10:14:12 +0200 Subject: [PATCH] add support for 3 dir shadow splits --- doc/classes/DirectionalLight.xml | 7 +- doc/classes/VisualServer.xml | 5 +- drivers/gles2/rasterizer_scene_gles2.cpp | 14 ++- drivers/gles2/shaders/scene.glsl | 111 ++++++++++++++++++++--- drivers/gles3/rasterizer_scene_gles3.cpp | 16 +++- drivers/gles3/shaders/scene.glsl | 42 +++++++++ scene/3d/light.cpp | 3 +- scene/3d/light.h | 1 + servers/visual/visual_server_scene.cpp | 3 + servers/visual_server.cpp | 1 + servers/visual_server.h | 1 + 11 files changed, 183 insertions(+), 21 deletions(-) diff --git a/doc/classes/DirectionalLight.xml b/doc/classes/DirectionalLight.xml index ac9988abedde..c0e0f18a663f 100644 --- a/doc/classes/DirectionalLight.xml +++ b/doc/classes/DirectionalLight.xml @@ -24,7 +24,7 @@ The maximum distance for shadow splits. Increasing this value will make directional shadows visible from further away, at the cost of lower overall shadow detail and performance (since more objects need to be included in the directional shadow rendering). - + The light's shadow rendering algorithm. See [enum ShadowMode]. @@ -48,7 +48,10 @@ Splits the view frustum in 2 areas, each with its own shadow map. This shadow mode is a compromise between [constant SHADOW_ORTHOGONAL] and [constant SHADOW_PARALLEL_4_SPLITS] in terms of performance. - + + Splits the view frustum in 3 areas, each with its own shadow map. This shadow mode is a compromise between [constant SHADOW_ORTHOGONAL] and [constant SHADOW_PARALLEL_4_SPLITS] in terms of performance. + + Splits the view frustum in 4 areas, each with its own shadow map. This is the slowest directional shadow mode. diff --git a/doc/classes/VisualServer.xml b/doc/classes/VisualServer.xml index 77e8191a78b1..f12c5bb5d2f6 100644 --- a/doc/classes/VisualServer.xml +++ b/doc/classes/VisualServer.xml @@ -3501,7 +3501,10 @@ Use 2 splits for shadow projection when using directional light. - + + Use 3 splits for shadow projection when using directional light. + + Use 4 splits for shadow projection when using directional light. diff --git a/drivers/gles2/rasterizer_scene_gles2.cpp b/drivers/gles2/rasterizer_scene_gles2.cpp index de4d2806dd99..25e997ff305c 100644 --- a/drivers/gles2/rasterizer_scene_gles2.cpp +++ b/drivers/gles2/rasterizer_scene_gles2.cpp @@ -514,6 +514,7 @@ int RasterizerSceneGLES2::get_directional_light_shadow_size(RID p_light_intance) case VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL: break; //none case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: + case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS: case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: shadow_size /= 2; break; @@ -1912,6 +1913,7 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_MODE_OMNI, false); state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_MODE_SPOT, false); state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM2, false); + state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM3, false); state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM4, false); state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM_BLEND, false); @@ -1933,6 +1935,9 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM2, true); } break; + case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS: { + state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM3, true); + } break; case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: { state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM4, true); } break; @@ -2020,6 +2025,10 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado shadow_count = 2; } break; + case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS: { + shadow_count = 3; + } break; + case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: { shadow_count = 4; } break; @@ -2031,7 +2040,7 @@ void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shado uint32_t width = light->directional_rect.size.x; uint32_t height = light->directional_rect.size.y; - if (light_ptr->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { + if (light_ptr->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS || light_ptr->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { width /= 2; height /= 2; @@ -2667,6 +2676,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, state.scene_shader.set_conditional(SceneShaderGLES2::USE_INSTANCING, false); state.scene_shader.set_conditional(SceneShaderGLES2::USE_RADIANCE_MAP, false); state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM4, false); + state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM3, false); state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM2, false); state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM_BLEND, false); state.scene_shader.set_conditional(SceneShaderGLES2::USE_VERTEX_LIGHTING, false); @@ -3714,7 +3724,7 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_ width = light_instance->directional_rect.size.width; height = light_instance->directional_rect.size.height; - if (light->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { + if (light->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS || light->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { width /= 2; height /= 2; diff --git a/drivers/gles2/shaders/scene.glsl b/drivers/gles2/shaders/scene.glsl index f9a127cb7348..8ac79ebd5858 100644 --- a/drivers/gles2/shaders/scene.glsl +++ b/drivers/gles2/shaders/scene.glsl @@ -166,18 +166,19 @@ uniform highp float shadow_dual_paraboloid_render_side; uniform highp mat4 light_shadow_matrix; varying highp vec4 shadow_coord; -#if defined(LIGHT_USE_PSSM2) || defined(LIGHT_USE_PSSM4) +#if defined(LIGHT_USE_PSSM2) || defined(LIGHT_USE_PSSM3) || defined(LIGHT_USE_PSSM4) uniform highp mat4 light_shadow_matrix2; varying highp vec4 shadow_coord2; #endif -#if defined(LIGHT_USE_PSSM4) - +#if defined(LIGHT_USE_PSSM3) || defined(LIGHT_USE_PSSM4) uniform highp mat4 light_shadow_matrix3; -uniform highp mat4 light_shadow_matrix4; varying highp vec4 shadow_coord3; -varying highp vec4 shadow_coord4; +#endif +#if defined(LIGHT_USE_PSSM4) +uniform highp mat4 light_shadow_matrix4; +varying highp vec4 shadow_coord4; #endif #endif @@ -625,14 +626,16 @@ VERTEX_SHADER_CODE vec4 vi4 = vec4(vertex_interp, 1.0); shadow_coord = light_shadow_matrix * vi4; -#if defined(LIGHT_USE_PSSM2) || defined(LIGHT_USE_PSSM4) +#if defined(LIGHT_USE_PSSM2) || defined(LIGHT_USE_PSSM3) || defined(LIGHT_USE_PSSM4) shadow_coord2 = light_shadow_matrix2 * vi4; #endif -#if defined(LIGHT_USE_PSSM4) +#if defined(LIGHT_USE_PSSM3) || defined(LIGHT_USE_PSSM4) shadow_coord3 = light_shadow_matrix3 * vi4; - shadow_coord4 = light_shadow_matrix4 * vi4; +#endif +#if defined(LIGHT_USE_PSSM4) + shadow_coord4 = light_shadow_matrix4 * vi4; #endif #endif //use shadow and use lighting @@ -1078,15 +1081,19 @@ uniform highp vec4 light_split_offsets; varying highp vec4 shadow_coord; -#if defined(LIGHT_USE_PSSM2) || defined(LIGHT_USE_PSSM4) +#if defined(LIGHT_USE_PSSM2) || defined(LIGHT_USE_PSSM3) || defined(LIGHT_USE_PSSM4) varying highp vec4 shadow_coord2; #endif -#if defined(LIGHT_USE_PSSM4) +#if defined(LIGHT_USE_PSSM3) || defined(LIGHT_USE_PSSM4) varying highp vec4 shadow_coord3; + +#if defined(LIGHT_USE_PSSM4) + varying highp vec4 shadow_coord4; +#endif #endif uniform vec4 light_clamp; @@ -2010,6 +2017,55 @@ FRAGMENT_SHADER_CODE #endif //LIGHT_USE_PSSM4 +#ifdef LIGHT_USE_PSSM3 + //take advantage of prefetch + float shadow1 = sample_shadow(light_directional_shadow, shadow_coord); + float shadow2 = sample_shadow(light_directional_shadow, shadow_coord2); + float shadow3 = sample_shadow(light_directional_shadow, shadow_coord3); + + if (depth_z < light_split_offsets.z) { + float pssm_fade = 0.0; + float shadow_att = 1.0; +#ifdef LIGHT_USE_PSSM_BLEND + float shadow_att2 = 1.0; + float pssm_blend = 0.0; + bool use_blend = true; +#endif + if (depth_z < light_split_offsets.y) { + if (depth_z < light_split_offsets.x) { + shadow_att = shadow1; + +#ifdef LIGHT_USE_PSSM_BLEND + shadow_att2 = shadow2; + + pssm_blend = smoothstep(0.0, light_split_offsets.x, depth_z); +#endif + } else { + shadow_att = shadow2; + +#ifdef LIGHT_USE_PSSM_BLEND + shadow_att2 = shadow3; + + pssm_blend = smoothstep(light_split_offsets.x, light_split_offsets.y, depth_z); +#endif + } + } else { + shadow_att = shadow3; + +#if defined(LIGHT_USE_PSSM_BLEND) + use_blend = false; +#endif + } +#if defined(LIGHT_USE_PSSM_BLEND) + if (use_blend) { + shadow_att = mix(shadow_att, shadow_att2, pssm_blend); + } +#endif + light_att *= mix(shadow_color.rgb, vec3(1.0), shadow_att); + } + +#endif //LIGHT_USE_PSSM3 + #ifdef LIGHT_USE_PSSM2 //take advantage of prefetch @@ -2050,7 +2106,7 @@ FRAGMENT_SHADER_CODE #endif //LIGHT_USE_PSSM2 -#if !defined(LIGHT_USE_PSSM4) && !defined(LIGHT_USE_PSSM2) +#if !defined(LIGHT_USE_PSSM4) && !defined(LIGHT_USE_PSSM3) && !defined(LIGHT_USE_PSSM2) light_att *= mix(shadow_color.rgb, vec3(1.0), sample_shadow(light_directional_shadow, shadow_coord)); #endif //orthogonal @@ -2060,6 +2116,8 @@ FRAGMENT_SHADER_CODE { #ifdef LIGHT_USE_PSSM4 if (depth_z < light_split_offsets.w) { +#elif defined(LIGHT_USE_PSSM3) + if (depth_z < light_split_offsets.z) { #elif defined(LIGHT_USE_PSSM2) if (depth_z < light_split_offsets.y) { #else @@ -2116,6 +2174,35 @@ FRAGMENT_SHADER_CODE #endif // LIGHT_USE_PSSM4 +#ifdef LIGHT_USE_PSSM3 + + if (depth_z < light_split_offsets.y) { + if (depth_z < light_split_offsets.x) { + pssm_coord = shadow_coord; + +#ifdef LIGHT_USE_PSSM_BLEND + pssm_coord2 = shadow_coord2; + pssm_blend = smoothstep(0.0, light_split_offsets.x, depth_z); +#endif + } else { + pssm_coord = shadow_coord2; + +#ifdef LIGHT_USE_PSSM_BLEND + pssm_coord2 = shadow_coord3; + pssm_blend = smoothstep(light_split_offsets.x, light_split_offsets.y, depth_z); +#endif + } + } else { + pssm_coord = shadow_coord3; + pssm_fade = smoothstep(light_split_offsets.y, light_split_offsets.z, depth_z); + +#if defined(LIGHT_USE_PSSM_BLEND) + use_blend = false; +#endif + } + +#endif // LIGHT_USE_PSSM3 + #ifdef LIGHT_USE_PSSM2 if (depth_z < light_split_offsets.x) { pssm_coord = shadow_coord; @@ -2134,7 +2221,7 @@ FRAGMENT_SHADER_CODE #endif // LIGHT_USE_PSSM2 -#if !defined(LIGHT_USE_PSSM4) && !defined(LIGHT_USE_PSSM2) +#if !defined(LIGHT_USE_PSSM4) && !defined(LIGHT_USE_PSSM3) && !defined(LIGHT_USE_PSSM2) { pssm_coord = shadow_coord; } diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index dd602bd39f51..e52dbd87e177 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -463,6 +463,7 @@ int RasterizerSceneGLES3::get_directional_light_shadow_size(RID p_light_intance) case VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL: break; //none case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: + case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS: case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: shadow_size /= 2; break; @@ -2037,9 +2038,9 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_DIRECTIONAL_SHADOW, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM4, false); + state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM3, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM2, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND, false); - state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND, false); state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5, false); state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13, false); state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES, false); @@ -2064,6 +2065,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL, use_directional); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_DIRECTIONAL_SHADOW, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM4, false); + state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM3, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM2, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND, false); state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5); @@ -2082,6 +2084,10 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM2, true); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND, directional_light->light_ptr->directional_blend_splits); break; + case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS: + state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM3, true); + state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND, directional_light->light_ptr->directional_blend_splits); + break; case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM4, true); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND, directional_light->light_ptr->directional_blend_splits); @@ -2224,6 +2230,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_DIRECTIONAL_SHADOW, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM4, false); + state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM3, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM2, false); state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND, false); state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS, false); @@ -2721,6 +2728,9 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: { shadow_count = 2; } break; + case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS: { + shadow_count = 3; + } break; case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: { shadow_count = 4; } break; @@ -2732,7 +2742,7 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform uint32_t width = li->directional_rect.size.x; uint32_t height = li->directional_rect.size.y; - if (li->light_ptr->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { + if (li->light_ptr->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS || li->light_ptr->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { width /= 2; height /= 2; @@ -4739,7 +4749,7 @@ void RasterizerSceneGLES3::render_shadow(RID p_light, RID p_shadow_atlas, int p_ width = light_instance->directional_rect.size.x; height = light_instance->directional_rect.size.y; - if (light->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { + if (light->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS || light->directional_shadow_mode == VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS) { width /= 2; height /= 2; diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index b0134c8a2581..a4d35a79b967 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -2129,11 +2129,15 @@ FRAGMENT_SHADER_CODE #ifdef LIGHT_USE_PSSM4 //ubershader-runtime value = shadow_split_offsets.w; #else //ubershader-runtime +#ifdef LIGHT_USE_PSSM3 //ubershader-runtime + value = shadow_split_offsets.z; +#else //ubershader-runtime #ifdef LIGHT_USE_PSSM2 //ubershader-runtime value = shadow_split_offsets.y; #else //ubershader-runtime value = shadow_split_offsets.x; #endif //ubershader-runtime +#endif //ubershader-runtime #endif //LIGHT_USE_PSSM4 //ubershader-runtime if (depth_z < value) { vec3 pssm_coord; @@ -2194,6 +2198,42 @@ FRAGMENT_SHADER_CODE #endif //LIGHT_USE_PSSM4 //ubershader-runtime +#ifdef LIGHT_USE_PSSM3 //ubershader-runtime + + if (depth_z < shadow_split_offsets.y) { + if (depth_z < shadow_split_offsets.x) { + highp vec4 splane = (shadow_matrix1 * vec4(vertex, 1.0)); + pssm_coord = splane.xyz / splane.w; + +#ifdef LIGHT_USE_PSSM_BLEND //ubershader-runtime + + splane = (shadow_matrix2 * vec4(vertex, 1.0)); + pssm_coord2 = splane.xyz / splane.w; + pssm_blend = smoothstep(0.0, shadow_split_offsets.x, depth_z); +#endif //ubershader-runtime + + } else { + highp vec4 splane = (shadow_matrix2 * vec4(vertex, 1.0)); + pssm_coord = splane.xyz / splane.w; + +#ifdef LIGHT_USE_PSSM_BLEND //ubershader-runtime + splane = (shadow_matrix3 * vec4(vertex, 1.0)); + pssm_coord2 = splane.xyz / splane.w; + pssm_blend = smoothstep(shadow_split_offsets.x, shadow_split_offsets.y, depth_z); +#endif //ubershader-runtime + } + } else { + highp vec4 splane = (shadow_matrix3 * vec4(vertex, 1.0)); + pssm_coord = splane.xyz / splane.w; + pssm_fade = smoothstep(shadow_split_offsets.y, shadow_split_offsets.z, depth_z); + +#ifdef LIGHT_USE_PSSM_BLEND //ubershader-runtime + use_blend = false; +#endif //ubershader-runtime + } + +#endif //LIGHT_USE_PSSM3 //ubershader-runtime + #ifdef LIGHT_USE_PSSM2 //ubershader-runtime if (depth_z < shadow_split_offsets.x) { @@ -2220,12 +2260,14 @@ FRAGMENT_SHADER_CODE #endif //LIGHT_USE_PSSM2 //ubershader-runtime #ifndef LIGHT_USE_PSSM2 //ubershader-runtime +#ifndef LIGHT_USE_PSSM3 //ubershader-runtime #ifndef LIGHT_USE_PSSM4 //ubershader-runtime { //regular orthogonal highp vec4 splane = (shadow_matrix1 * vec4(vertex, 1.0)); pssm_coord = splane.xyz / splane.w; } #endif //ubershader-runtime +#endif //ubershader-runtime #endif //ubershader-runtime //one one sample diff --git a/scene/3d/light.cpp b/scene/3d/light.cpp index 9ce3585df65c..dbf3d516e5c5 100644 --- a/scene/3d/light.cpp +++ b/scene/3d/light.cpp @@ -386,7 +386,7 @@ void DirectionalLight::_bind_methods() { ClassDB::bind_method(D_METHOD("is_blend_splits_enabled"), &DirectionalLight::is_blend_splits_enabled); ADD_GROUP("Directional Shadow", "directional_shadow_"); - ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_mode", PROPERTY_HINT_ENUM, "Orthogonal (Fast),PSSM 2 Splits (Average),PSSM 4 Splits (Slow)"), "set_shadow_mode", "get_shadow_mode"); + ADD_PROPERTY(PropertyInfo(Variant::INT, "directional_shadow_mode", PROPERTY_HINT_ENUM, "Orthogonal (Fast),PSSM 2 Splits (Average),PSSM 3 Splits (Slow),PSSM 4 Splits (Very Slow)"), "set_shadow_mode", "get_shadow_mode"); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_1", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_1_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_2", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_2_OFFSET); ADD_PROPERTYI(PropertyInfo(Variant::REAL, "directional_shadow_split_3", PROPERTY_HINT_RANGE, "0,1,0.001"), "set_param", "get_param", PARAM_SHADOW_SPLIT_3_OFFSET); @@ -398,6 +398,7 @@ void DirectionalLight::_bind_methods() { BIND_ENUM_CONSTANT(SHADOW_ORTHOGONAL); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_2_SPLITS); + BIND_ENUM_CONSTANT(SHADOW_PARALLEL_3_SPLITS); BIND_ENUM_CONSTANT(SHADOW_PARALLEL_4_SPLITS); BIND_ENUM_CONSTANT(SHADOW_DEPTH_RANGE_STABLE); diff --git a/scene/3d/light.h b/scene/3d/light.h index c5c058d94854..bfdf4f79354e 100644 --- a/scene/3d/light.h +++ b/scene/3d/light.h @@ -139,6 +139,7 @@ class DirectionalLight : public Light { enum ShadowMode { SHADOW_ORTHOGONAL, SHADOW_PARALLEL_2_SPLITS, + SHADOW_PARALLEL_3_SPLITS, SHADOW_PARALLEL_4_SPLITS }; diff --git a/servers/visual/visual_server_scene.cpp b/servers/visual/visual_server_scene.cpp index 676b2f830d71..8246bf498e3b 100644 --- a/servers/visual/visual_server_scene.cpp +++ b/servers/visual/visual_server_scene.cpp @@ -2490,6 +2490,9 @@ bool VisualServerScene::_light_instance_update_shadow(Instance *p_instance, cons case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: splits = 2; break; + case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS: + splits = 3; + break; case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: splits = 4; break; diff --git a/servers/visual_server.cpp b/servers/visual_server.cpp index f56e42027756..80552aa65e79 100644 --- a/servers/visual_server.cpp +++ b/servers/visual_server.cpp @@ -2375,6 +2375,7 @@ void VisualServer::_bind_methods() { BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL); BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS); + BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS); BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS); BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_STABLE); BIND_ENUM_CONSTANT(LIGHT_DIRECTIONAL_SHADOW_DEPTH_RANGE_OPTIMIZED); diff --git a/servers/visual_server.h b/servers/visual_server.h index a3f6878a7c53..ef95063bd3c1 100644 --- a/servers/visual_server.h +++ b/servers/visual_server.h @@ -489,6 +489,7 @@ class VisualServer : public Object { enum LightDirectionalShadowMode { LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL, LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS, + LIGHT_DIRECTIONAL_SHADOW_PARALLEL_3_SPLITS, LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS };