Browse Source

Merge pull request #99536 from lawnjelly/faster_shadow_fade

[3.x] Ameliorate performance regression due to directional shadow `fade_start`
lawnjelly 9 months ago
parent
commit
b1ea48d913

+ 4 - 1
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -2799,7 +2799,10 @@ void RasterizerSceneGLES3::_setup_directional_light(int p_index, const Transform
 		const float fade_start = li->light_ptr->param[VS::LIGHT_PARAM_SHADOW_FADE_START];
 		// Using 1.0 would break `smoothstep()` in the shader.
 		ubo_data.fade_from = -ubo_data.shadow_split_offsets[shadow_count - 1] * MIN(fade_start, 0.999);
-		ubo_data.fade_to = -ubo_data.shadow_split_offsets[shadow_count - 1];
+
+		// To prevent the need for a fade to, store the fade to in the final split offset.
+		// It will either be the same as before, or the maximum split offset.
+		ubo_data.shadow_split_offsets[3] = ubo_data.shadow_split_offsets[shadow_count - 1];
 	}
 
 	glBindBuffer(GL_UNIFORM_BUFFER, state.directional_ubo);

+ 1 - 2
drivers/gles3/rasterizer_scene_gles3.h

@@ -592,8 +592,7 @@ public:
 		float shadow_split_offsets[4];
 
 		float fade_from;
-		float fade_to;
-		float pad[2];
+		float pad[3];
 	};
 
 	struct LightInstance : public RID_Data {

+ 3 - 5
drivers/gles3/shaders/scene.glsl

@@ -148,8 +148,7 @@ layout(std140) uniform DirectionalLightData { //ubo:3
 	mediump vec4 shadow_split_offsets;
 
 	mediump float fade_from;
-	mediump float fade_to;
-	mediump vec2 pad;
+	mediump vec3 pad;
 };
 
 #endif //ubershader-skip
@@ -848,8 +847,7 @@ layout(std140) uniform DirectionalLightData {
 	mediump vec4 shadow_split_offsets;
 
 	mediump float fade_from;
-	mediump float fade_to;
-	mediump vec2 pad;
+	mediump vec3 pad;
 };
 
 uniform highp sampler2DShadow directional_shadow; // texunit:-5
@@ -2292,7 +2290,7 @@ FRAGMENT_SHADER_CODE
 			shadow = min(shadow, contact_shadow);
 		}
 #endif //ubershader-runtime
-		float pssm_fade = smoothstep(fade_from, fade_to, vertex.z);
+		float pssm_fade = smoothstep(fade_from, -shadow_split_offsets.w, vertex.z);
 		light_attenuation = mix(mix(shadow_color_contact.rgb, vec3(1.0), shadow), vec3(1.0), pssm_fade);
 	}