Projecting a texture

i had been using stencil shadows so far, but i’d like to give shadow mapping a try. ok, so i render the scene depth from the light’s point of view into a fbo. i’m now at the next step, projecting the texture onto my geometry. i’ve applied this shader to the floor:


uniform mat4 u_ViewMatrix;
uniform mat4 u_ViewMatrixInverse;

uniform mat4 u_ProjectionMatrix;

uniform mat4 u_ModelMatrix;
uniform mat4 u_LightMatrix;

varying vec4 v_Projection;

void main()
	gl_Position = u_ProjectionMatrix*(u_ViewMatrix*u_ModelMatrix*gl_Vertex);

	mat4 bias = mat4(0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, 0.0, 0.5, 0.5, 0.5, 1.0 );

	v_Projection = bias*u_ProjectionMatrix*u_LightMatrix*u_ViewMatrixInverse*(u_ViewMatrix*u_ModelMatrix*gl_Vertex);


uniform sampler2D u_Texture0;

varying vec4 v_Projection;

void main()
	gl_FragColor = texture2DProj( u_Texture0, v_Projection );

the result:


the texture is projected onto the floor, but it seems to be aligned to the camera rather than the floor’s surface :stuck_out_tongue: what am i doing wrong? thanks!

It’s because you are using the camera projection/modelview matrix, what you really need is the light projection and modelview matrix.
I wrote a small tutorial about this, i am sure you can extract the relevant bit’s.

ARGH i’m an idiot! reading your tutorial i realized that i forgot to force recomputation of the matrices -.- thanks!

Also, for performance reasons you should consider adding parantheses to your matrix multiplications above. Keep in mind that evaluation is left to right and matrix by matrix multiplication is a lot more expensive than matrix by vector multiplication.

ok how should i place them?

Originally posted by Vexator:
ok how should i place them?
for example like this:


I would multiply all that matrices into one in the mainprogram (CPU side). That will be much faster than doing 5 Matrix * Vector multiplication for each Vertex.

thank you!

this is what it looks like with a 4096² shadow map. the shadows themselves are fine, but there are still a lot of self shadowing artifacts.

i’ll get rid of them somehow, but first there are two more important iusses:

  1. what’s the right way to setup the light’s projection matrix? should i use an orthographic or and perspective one? and should i use the screen’s aspect ratio (which is 4:3) or the shadow map’s (which is 1:1 of course)? atm i’m using the shadow map’s ratio, which displays the shadows correctly, but the spotlight texture is stretched horizontally. if i use the shadow map’s ratio, the spotlight texture is perfectly round, but the shadows are misplaced sigh

  2. i would like to blur the shadow to improve visual quality. i know how to blur a vec2, but how should i setup an appropiate kernel for a vec4?

thanks :smiley:

  1. orthographic or perspective projection, it all depends on what the lightsource is, for the sun orthographic might be the best and projection is best for spotlights, use whatever looks the best.
    a 1:1 ratio is the best ratio, you should also change your viewport to fit this ratio when rendering the depth map.

  2. the same way as a vec 2(when reading from the texture, only the two first ones really matter for blurring), but you do need to test the depth values individually for each sample.
    You could also use light jittering, but that takes a lot of time and memory.

And finally, a lot of self shadowing artifacts can be hidden by multiplying the shadow value with the diffuse value

thanks overlord! :smiley: i got rid of most artifacts and i managed to soften the shadows :smiley: i have not solved the problem with my projection matrix, although i am setting up the viewport correctly, though. i’ll figure it out somehow.

next question - can i perform the deopth values comparison myself, i.e. using sampler2D instead of sampler2DShadow? i would like to soften the shadows according to the distance from their casters, so i need to be able to access the original depth values.

Yes, you can sample a depth texture with sampler2D and get the actual depth.

and then? what do i have to compare it with? and how? a simple less/greater test?

//edit: k i got it:

float Shadow = texture2DProj( u_Texture2, v_Projection ).r < ( v_Projection.z/v_Projection.w )  ? 0.0 : 1.0;

does the trick. however, the shadow map is not being anti-alisased then. mpfh.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.