2x2 PCF Lerp shadow map problem

Started by
5 comments, last by Postie 12 years, 5 months ago
I'm trying to implement the same shadow mapping algorithm described here:
http://www.gamedev.n...ping-technique/

in the Source engine. However, I've run into some problems I can't solve:
2011-04-26_00004.jpg

I sort of see what's going on. The texels should be 'flipped around', but I am not sure how to do this...

Here's my code:


float PCF2x2Lerp( sampler DepthSampler, const float3 vProjCoords )
{

// Define center of shadow filter
float2 shadowMapCenter = vProjCoords.xy;

// Define shadow map size
float shadowMapSize = 1024;

// Get texel size
float2 texelSize = 1.0 / shadowMapSize;
// Offset the texcoords by half a texel
float2 offsetTex = texelSize / 2;

// Object depth in shadow space
float objDepth = min( vProjCoords.z, 0.99999 );

// Get four shadowmap samples at the corners
float4 tap;
// X O
// O O
tap.x = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -offsetTex.x, offsetTex.y ), objDepth, 1 ) ).x;
// O Y
// O O
tap.y = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( offsetTex.x, offsetTex.y ), objDepth, 1 ) ).x;
// O O
// Z O
tap.z = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( -offsetTex.x, -offsetTex.y ), objDepth, 1 ) ).x;
// O O
// O W
tap.w = tex2Dproj( DepthSampler, float4( shadowMapCenter + float2( offsetTex.x, -offsetTex.y ), objDepth, 1 ) ).x;

// Get the fractional xy position of the fragment within the texel
float2 fpos = frac(vProjCoords.xy * shadowMapSize);

// Interpolate the texel shadow factor
float r1 = lerp(tap.y, tap.x, fpos.x);
float r2 = lerp(tap.w, tap.z, fpos.x);
float shadowFactor = lerp(r1, r2, fpos.y);

return shadowFactor;
}


Thanks!
Advertisement
Stupid question, but have you tried inverting the order that the taps appear in the lerp intrinsic?

(i.e. float r1 = lerp(tap.y, tap.x, fpos.x) becomes float r1 = lerp(tap.x, tap.y, fpos.x) and so forth)

EDIT: Wow, that looks horrible. Hopefully you can get the gist of it, though.
clb: At the end of 2012, the positions of jupiter, saturn, mercury, and deimos are aligned so as to cause a denormalized flush-to-zero bug when computing earth's gravitational force, slinging it to the sun.
Lerp Derp. Sorry, had to. :S
Try to set MagFilter = Point; / pID3DDevice->SetSamplerState(st, D3DSAMP_MAGFILTER, D3DTEXF_POINT); for your shadowmap texture
I ran into some similar visual arfifact with shadowmap & lerp when I was using LINEAR filtering on the texture.
Hi!

David Tuft held at Gamesfest in 2010 a nice talk on shadow mapping, where he covered some basic problems and provided little code fragments to get pass them.
It's a one hour talk, which is definitely worth listening to, especially if you're just starting with shadow mapping. Slides and audio track can be found here at the MSDN download center.
Have fun with that. ;)

Try to set MagFilter = Point; / pID3DDevice->SetSamplerState(st, D3DSAMP_MAGFILTER, D3DTEXF_POINT); for your shadowmap texture
I ran into some similar visual arfifact with shadowmap & lerp when I was using LINEAR filtering on the texture.


exactly - also had a similar problem once - and point sampling did solve it.
I believe the issue is that you're looking at the wrong pixels for your taps. You're sampling the 4 pixels in the diagonal corners around the source pixel, like this:
(X represents source pixel, O represents sampled pixel)

O O
X
O O

When in fact the sampling should be like this:

XO
OO

(*note X is also part of the tap)

If you look carefully at the original code you linked, the offsets are different in yours.
[size="2"]Currently working on an open world survival RPG - For info check out my Development blog:[size="2"] ByteWrangler

This topic is closed to new replies.

Advertisement