• ### Popular Now

• 12
• 12
• 9
• 10
• 13

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

## Recommended Posts

Hi there, I'm currently working on soft shadow mapping. I have an idea of doing soft penumbra on the shadow map. I want to be able to blur the shadow based upon it's distance from the shadow caster. If I have the depth value of the shadow, stored in the depth map, how can I get the depth of the fragment from the lights point of view. I intend on subtracting the shdow depth from the fragment depth to get a blur offset which will then be used for blurring the shadow map. Can anyone point me in the right direction, and also about converting the depth from 0-1 range into world units.

##### Share on other sites
There is an example of this in Beginning OpenGL Game Programming that creates a soft shadow by using the accumulation buffer and jittering the light position back and forth to create a light source with volume. Instead of infinitely small light sources like in openGL. A shadow projection matrix is calculated using the new light position and then a cone is projected onto the floor plane and drawn as a black shadow. The results are accumulated with a factor based on the total number of samples.

Both the plane and the shadow are drawn every iteration, but the plane stays still while the shadow moves slightly due to the jittered light source. This results in the shadow having a dark center and lighter edges because the center pixels were rendered every time.

I haven't really dug too deeply into this sample, so if you have any more questions about it I can probably just post the function they use in the book to give you a better idea.

##### Share on other sites
I've got that working, using PCF, cheers.

What I need to know, is the distance between a shadow caster and receiver, so I can use this to compute a soft penumbra on the shadow. I'm presuming the best way to do this is by using depth values.

##### Share on other sites
Right.

I've come up with half a solution based upon blurring the depth map with a PCF kernel.

I can get the fragments distance from the light, by doing length(gl_Vertex-LightPos).

One thing I need to know is how to convert the scalar depth value into world units, so I can determine the distance the occluder is from the shadowed fragment.

If the near frustum is say at 1.0f, and the far frustum at 500.0f, I presume the the depth value is a log value between 1.0 and 500.0 right?

How do I convert this log depth value into a linear value between 1.0 and 500.0f?

##### Share on other sites
Cmon,

Someone out there must know how to get distances from a shadow caster to a fragment using a depth buffer for the shadow caster.

##### Share on other sites
I've found this formula that should convert from depth value to eye z coordinate:

a=-far/(far-near)
b=-far*near/(far-near)
Z=(a*z+b)/-z

I still have to try it, so I don't know if it works.
What you could try is the following:
-Get the depth value from the shadow map: you may need to use another texture unit bound to the shadow map, because otherwise you may not be able to read the depth value. Use the formula to transform the depth value first in light space and then in eye space.
-Get the fragment position and calculate the distance between the two points.

Let me know if that works, because I was interested too.

##### Share on other sites
Right,

I'm now mapping the linear distance from the light to the fragment (0.0-1.0) for the light frustum ( near = 1.0, far = 500.0).

		vec4 l_pos	=	gl_LightSource[0].position;		vec4 f_pos	=	gl_ModelViewMatrix * vec4(cullvertex,1);		float far	=	500.0;		float near	=	1.0;		float dist  =   (1/far)*(abs(length(f_pos-l_pos))+near);

cullvertex is just gl_Vertex from the vert shader.

And this is what I get.

Now I need the occluder's distance from the light, which is stored in the depth buffer. Ive tries using the depth texture with sampler2D and texture2DProj, but am having no luck.

If I can subtract the depth texture from the fragment depth, then it will solve the obvious problem with the shadow penumbra in the image below...

Any ideas?

[Edited by - Lopez on May 24, 2006 1:20:00 PM]

##### Share on other sites
Well, if I got your problem right, you have your shadow map and want to get the distance of every single texel. To get this, I used the following formula:

float z = 100.0*0.1/(100.0-depth.x*(100.0-0.1));

where 100.0 is my far plane and 0.1 is my near plane. depth.x is the depth texture value got with texture2D(). Apparently, you cannot both read the depth value and use the shadow2d() function for comparation. To do that, you will need to bind the same depth texture to two samplers (using two units).