# Jittered shadow map, wrong results

## Recommended Posts

Hello, I'm trying to get soft shadow mapping by using jittered samples per pixel but unfortunately I'm getting strange results: As you can see, the shadow is a bit jittered but the transition is not soft. In fact, the aliased shadow is still visible in the middle of the jittered effect. For the jittering I'm using a disk of 16 sampling positions that are passed to the shader as constants and are "randomly" rotated per-pixel. The random rotation is performed by reading a texture that contains a different rotation angle per pixel which is used to generate a 2D rotation matrix that is applied to all the sampling positions (not the most efficient solution, I know). The shadowmap sampling and depth comparison is done manually since I'm using linear depth shadowmaps. Here is the code. Can someone tell me what is the problem?
#define MAX_SAMPLES	32

uniform vec2		samplingVectors[MAX_SAMPLES];
uniform int			numSamples;
uniform sampler2D	noiseTexture;

float result= 0.0;
float kernelRotationAngle= texture2D(noiseTexture, gl_TexCoord[0].st*vec2(42.5, 32.8)*2.0).x*2.0*3.14;
mat2 kernelRotationMatrix= mat2(cos(kernelRotationAngle), -sin(kernelRotationAngle), sin(kernelRotationAngle), cos(kernelRotationAngle));

for(int i= 0; i< numSamples; ++i){

result+= 1.0;
}

return result/numSamples;
}


[Edited by - jcabeleira on February 23, 2010 8:19:02 PM]

##### Share on other sites
Can you post a list of the vectors you pass in as the samplingVectors[MAX_SAMPLES] uniform? My guess would be that they contain some zero-vectors or a high amount of small vectors.

##### Share on other sites
The problem isn't the vectors, I've checked that.
Currently the vectors are randomly generated which could cause the problem you mentioned. To exclude that possibility I've replaced them by a poisson disk, that I got from an NVidia sample, but the problem remains.

##### Share on other sites
Show us a screen with fewer samples and one with more if possible.

Also what happens if you don't rotate your kernel?

That line could be a lot of things. Such as your sample vectors being too small... or perhaps its a rounding error.

##### Share on other sites
I've manage to get good results, but the way I've done is weird.
I remembered that most smoothing filters require an weight factor based on the distance of each sample to the center of the filter kernel. Intuitively, distant samples should have less impact on the shadow than closer samples. I've added that weight factor but I still got wrong results.

I turns out that it only works if I use the inverted weight function, where distant samples have more impact on the shadow result than closer ones! But does that make sense?

Here is the code. Since each sampling vectors has a length between 0 and 1, I use it to weight the sample. The final result is then renormalized to account for the weighting:

#define MAX_SAMPLES	64uniform vec2		samplingVectors[MAX_SAMPLES];uniform int			numSamples;uniform sampler2D	noiseTexture;float sampleSoftShadowMap(sampler2D shadowMap, vec4 shadowTexCoord, float kernelRadius= 0.007){	float result= 0.0;	float kernelRotationAngle= texture2D(noiseTexture, gl_TexCoord[0].st*vec2(42.5, 32.8)*2.0).x*2.0*3.14;	mat2 kernelRotationMatrix= mat2(cos(kernelRotationAngle), -sin(kernelRotationAngle), sin(kernelRotationAngle), cos(kernelRotationAngle));	vec2 texcoord= shadowTexCoord.xy/shadowTexCoord.w*0.5+ 0.5;		float sum= 0.0f;	for(int i= 0; i< numSamples; ++i){		float occluderDepth= texture2D(shadowMap, texcoord+ samplingVectors[i]*kernelRotationMatrix*kernelRadius*5.0).x;				if(shadowTexCoord.z< occluderDepth+ 0.005)			result+= length(samplingVectors[i]);					sum+= length(samplingVectors[i]);	}		return result/sum;

##### Share on other sites
It all depends how you generated your sampling vectors. By any chance did you do it by generating a random length and a random angle? That would explain your problem, and also why weighting by the length fixed it.

##### Share on other sites
Yes the vectors were generated with random angle and random length (length between 0 and 1). Is there a problem with this approach?

Anyway, like I said before, I replaced it by a poisson disk but the problem remains.

##### Share on other sites
Yeah that's the problem then. Choose the length of your vector as length = sqrt(random(0,1)). This will give you a uniform distribution of vectors in two dimensions. Note that if you do this, don't weight your samples by their distance.

##### Share on other sites

I spent a few minutes figuring out why it worked and I think I understood it. The problem is that I was using a random angle and length because I believed that it would provide the most uniform distribution, but that is not correct for disc shapes since it assumes that each sample represents the same area.
On a disc shape, the samples that are more distant to the kernel represent a wider area and so should have a bigger weight. Instead of weighting each sample, your trick just distributes more samples distant to the kernel center to compensate.

Did I got it right?

##### Share on other sites
You're welcome, I'm glad it worked. Your explanation of why it works is exactly right. I'd just add that the reason you make length = sqrt(random) is that area = length^2 = random. Thus the areas are uniformly distributed, so there will be the same number of samples in any fixed area.

##### Share on other sites
One more thing, pragma, could you also tell me how to pull the same trick on a sphere?

I just realized that I have a sky-dome sampling algorithm that doesn't weights each sample according to the area of the dome it represents. And that may be the reason why the results seem a little weird.

##### Share on other sites
Yeah, no problem. If theta is the polar angle and phi is the azimuthal angle, then let
theta = acos(random(0,1))
phi = random(0, 2 pi)
This will sample the upper hemisphere. If you want the whole sphere just set
theta = acos(random(-1,1))

##### Share on other sites
Thanks, once again it worked fine!

Meanwhile I found a resource called "Global Illumination Compendium" that contains these and many other formulas. Its very usefull stuff for anyone that is developing any kind of sampling algorithm.

## Create an account

Register a new account

• ## Partner Spotlight

• ### Forum Statistics

• Total Topics
627682
• Total Posts
2978615

• 13
• 12
• 10
• 12
• 22