Browse Source

Fix off-by-one error in computing shadow map texture coordinates

texture2DShadowLerp needs to calculate the texture coordinates of the four neighboring texels of the sample point.

Let's consider a texture with the size W * H. The centroids of the texels in this texture lie at texture coordinates [(X + 0.5) / W, (Y + 0.5) / H] where X and Y are integers.

To find the neighboring texel on the left of the sample point texture coordinate x, we want to find the maximum integer X for which:

(X + 0.5) / W < x <=>
X + 0.5 < x * W <=>
X < x * W - 0.5

We get this X value with floor( x * W - 0.5 ) and the corresponding texel centroid x coordinate is (floor( x * W - 0.5 ) + 0.5) / W.

For x = 1.3 and W = 2.0 this formula gives out 0.5 / 2.0. With the same values the previous formula would give out 1.0 / 2.0 which lies exactly at the texel boundary and so would end up sampling the wrong texel.
Olli Etuaho 6 years ago
parent
commit
ac2620dae3
1 changed files with 1 additions and 1 deletions
  1. 1 1
      src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js

+ 1 - 1
src/renderers/shaders/ShaderChunk/shadowmap_pars_fragment.glsl.js

@@ -41,7 +41,7 @@ export default /* glsl */`
 		const vec2 offset = vec2( 0.0, 1.0 );
 
 		vec2 texelSize = vec2( 1.0 ) / size;
-		vec2 centroidUV = floor( uv * size + 0.5 ) / size;
+		vec2 centroidUV = ( floor( uv * size - 0.5 ) + 0.5 ) * texelSize;
 
 		float lb = texture2DCompare( depths, centroidUV + texelSize * offset.xx, compare );
 		float lt = texture2DCompare( depths, centroidUV + texelSize * offset.xy, compare );