- float depth = 0.0;
- float pointDepth;
- float maxRadius = SOFTSHADOWRADIUS * 5.0 * multiplier;
-
- float bound = clamp(PCFBOUND * (1 - baseLength), 0.0, PCFBOUND);
- int n = 0;
-
- for (y = -bound; y <= bound; y += 1.0)
- for (x = -bound; x <= bound; x += 1.0) {
- clampedpos = vec2(x,y);
- perspectiveFactor = getDeltaPerspectiveFactor(baseLength + length(clampedpos) * texture_size * maxRadius);
- clampedpos = clampedpos * texture_size * perspectiveFactor * maxRadius * perspectiveFactor + smTexCoord.xy;
-
- pointDepth = getHardShadowDepth(shadowsampler, clampedpos.xy, realDistance);
- if (pointDepth > -0.01) {
- depth += pointDepth;
- n += 1;
- }
- }
-
- depth = depth / n;
- depth = pow(clamp(depth, 0.0, 1000.0), 1.6) / 0.001;
-
- perspectiveFactor = getDeltaPerspectiveFactor(baseLength);
- return max(length(smTexCoord.xy) * 2 * 2048 / f_textureresolution / pow(perspectiveFactor, 3), depth * maxRadius);
+ float depth = getHardShadowDepth(shadowsampler, smTexCoord.xy, realDistance);
+ // A factor from 0 to 1 to reduce blurring of short shadows
+ float sharpness_factor = 1.0;
+ // conversion factor from shadow depth to blur radius
+ float depth_to_blur = f_shadowfar / SOFTSHADOWRADIUS / xyPerspectiveBias0;
+ if (depth > 0.0 && f_normal_length > 0.0)
+ // 5 is empirical factor that controls how fast shadow loses sharpness
+ sharpness_factor = clamp(5 * depth * depth_to_blur, 0.0, 1.0);
+ depth = 0.0;
+
+ float world_to_texture = xyPerspectiveBias1 / perspective_factor / perspective_factor
+ * f_textureresolution / 2.0 / f_shadowfar;
+ float world_radius = 0.2; // shadow blur radius in world float coordinates, e.g. 0.2 = 0.02 of one node
+
+ return max(BASEFILTERRADIUS * f_textureresolution / 4096.0, sharpness_factor * world_radius * world_to_texture * SOFTSHADOWRADIUS);