Unity Yann's Lerp Shadow Mapping Technique

This topic is 4868 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

Recommended Posts

I was reading the other day about shadows on gamedev and came around the posts that Yann made for getting good results for shadow mapping. He gave some basic psuedo code for doing a type of PCF shadow mapping, but instead of just taking surrounding pixels of the shadow map and adding them together, he does a linear interpolation of some sort. I tried doing something like that with GLSL with the small snippet he gave (and the other person corrected). Here is the post: http://www.gamedev.net/community/forums/topic.asp?topic_id=256459 The other person posting named Ysaneya showed pictures on how his shadow mapping was banding too much. So Yann gave this code (after Ysaneya's corrections):
// Offset the texcoords by half a texel
ofstex = fragment.texcoord[0] - (0.5 / mapsize)

// Texel size
tsize = 1.0 / mapsize

// Get four shadowmap samples at the corners
s1 = ShadowSample(ofstex.x, ofstex.y)
s2 = ShadowSample(ofstex.x+tsize.x, ofstex.y)
s3 = ShadowSample(ofstex.x, ofstex.y+tsize.y)
s4 = ShadowSample(ofstex.x+tsize.x, ofstex.y+tsize.y)

// Get the fractional xy position of the fragment within the texel
fpos = fraction(fragment.texcoord[0] * mapsize)

// Interpolate the texel shadow factor
r1 = lerp(s1, s2, fpos.x)
r2 = lerp(s3, s4, fpos.x)
shadowfactor = lerp(r2, r1, fpos.y)

I tried to do this in GLSL and got this:
void main ()
{
vec4 color = gl_Color;

vec3 shadowUV_OG = projCoord.xyz / projCoord.q;

vec3 shadowUV = shadowUV_OG - (0.5 / 512.0);

float mapScale = 1.0 / 512.0;

vec3 fractPos = fract(shadowUV_OG * 512.0);

float r1 = s1.x + fractPos.x * (s2.x - s1.x);
float r2 = s3.x + fractPos.x * (s4.x - s3.x);
float shadowFactor = r2 + fractPos.y * (r1 - r2);

gl_FragColor = color * shadowFactor;
}

But I get these results on shadows (this is a sphere's shadow): Is my interpretation of the psuedo code wrong? I am not sure about the fract() function in GLSL if that is what he means. Any help would be great.

Share on other sites
I might be way off, but just by looking at the screen shot, it seems to me that the interpolation weights are inverted.

Share on other sites
Try:
float r1 = s2.x + fractPos.x * (s1.x - s2.x);
float r2 = s4.x + fractPos.x * (s3.x - s4.x);

Share on other sites
Hey cool, that KINDA worked :)

Now it looks like this:

It looks like there is shaded spheres in the outside pixels. Weird. If you look at the other guy's pictures in the post I mention at the top, the Coliseum image has banding, but the guy said it looked better than the bands but didn't give a final image. I imagine it looked better than this :) Any thoughts?

Share on other sites
Looking at your pic again, it seems like your shadow map resolution is alot less than 512.
I suggest that you change the shader constants to the resoultion of your texture.

Share on other sites
Nope, it's 512x512. Here is a good version with some decent PCF, not Yann's technique but just about 13 samples.

• What is your GameDev Story?

In 2019 we are celebrating 20 years of GameDev.net! Share your GameDev Story with us.

(You must login to your GameDev.net account.)

• 14
• 12
• 29
• 11
• 44
• Forum Statistics

• Total Topics
634856
• Total Posts
3019661
×