View Full Version : Planar shadows in Space,..

07-29-2011, 01:18 PM
Hi everyone - I found this tutorial on devmaster.
<a href="http://read.pudn.com/downloads117/sourcecode/windows/opengl/498282/schatten.cpp__.htm
" rel="nofollow" target="_blank">tutorial</a>

I managed to get it into my project.
Here's the Problem. I have a Plane I'm casting the shadow "onto" - now if there's a shadow that goes over the edge of this plan - it casts a shadow in the air,..

Since I don't understand what's going on in the code - maybe one of you guys could help me out? Hint?!

The relevant part:

void glShadowProjection(float * l, float * e, float * n)
float d, c;
float mat[16];

// These are c and d (corresponding to the tutorial)
d = sNormal[0]*l[0] + sNormal[1]*l[1] + sNormal[2]*l[2];
c = sPlane[0]*sNormal[0] + sPlane[1]*sNormal[1] + sPlane[2]*sNormal[2] - d;

// Creating matrix. (Column by column ordering)
mat[0] = sLight[0]*sNormal[0]+c;
mat[4] = sNormal[1]*sLight[0];
mat[8] = sNormal[2]*sLight[0];
mat[12] = -sLight[0]*c-sLight[0]*d;

mat[1] = sNormal[0]*sLight[1];
mat[5] = sLight[1]*sNormal[1]+c;
mat[9] = sNormal[2]*sLight[1];
mat[13] = -sLight[1]*c-sLight[1]*d;

mat[2] = sNormal[0]*sLight[2];
mat[6] = sNormal[1]*sLight[2];
mat[10] = sLight[2]*sNormal[2]+c;
mat[14] = -sLight[2]*c-sLight[2]*d;

mat[3] = sNormal[0];
mat[7] = sNormal[1];
mat[11] = sNormal[2];
mat[15] = -d;

// Multiply the matrices together.

Thanks a lot!

07-29-2011, 03:45 PM
In this technique You are not casting shadow on anything,
instead You define linear transformation which 'squashes' objects so they look like shadows (and render them with grey or black).

Any linear transformation can be represented by matrix.
read this:
to understand details of math behind this.

07-30-2011, 03:18 AM
Thanks for your answer. Yes that's basically what I meant. But I have a plane underneath to make it look like it's casting a shadow onto it.

Is it possible to cut off the Shadow if it exceeds a specific coordinate?
I have a square in the center - if the shadow reaches x = 10 -> cut off.

Is that possible ? And how?

PS: Thanks for the link - basic matrix transformation I understand - Rotation and so on are not a problem... glRotate(); - but here he does everything manually. At least that's what it looks like. I don't get it,... :confused:

07-30-2011, 05:28 AM
This is a classic case for using the stencil buffer.
First ensure you have attached a stencil buffer along with a depth buffer to your context.
Clear the stencil along with depth every frame. When you draw the plane object set the stencil ref value to say 01.
When you draw your shadow object set the stencil test to only pass when stencil buffer is 01 - ie where you have drawn the plane.

07-30-2011, 05:45 AM
If You are using legacy fixed-function, you can set clip plane

Alternatively You can write some values to depth buffer outside geometry on which You are casting shadows.
(unwanted fragments will fail depth test, and won't be rendered)

Or if You are using shaders You can modify coordinates of vertices which fall outside predefined range.
(It's not optimal, but for small objects it should work, nobody should notice displaced vertices, becuse everything is going to be black/gray - shadow)

something like:
if(vertex.x >= 10.0)
vertex.x = 10.0;

// do the transformations etc..

// or better without branch:
vertex.x = 10.0 + (vertex.x-10.0)*step(10.0, vertex.x);

or discard unwanted fragments in fragment shader, or even better - use stenciling