View Full Version : Shadow volume

12-05-2000, 06:52 PM

I was thinking about shadows in the past few days and for what I read, it seem that shadow volume seem to be a great way to create convincing shadows.... I read there : http://www.opengl.org/developers/code/features/StencilTalk/sld031.htm

that I need to build a shadow silhouette with glu tessellators and feed back buffer...

Could some body could guide me a little more on this please...

Is there a way to do that without having to use tessellators? If not, how could they help?
How could I get that to work with feedback buffer?

Thank you.

[This message has been edited by Gabriel (edited 12-05-2000).]

12-06-2000, 01:13 AM
Have a look on nVidia's web site for their excellent docs and demos on shadows. I wouldn't use the feedback buffer or the gluTesselators. The best way that I'm aware of to pull off shadow volumes is to use the stencil buffer and meshes with precomputed adjacency information. There's also a good doc on Intels' developer site somewhere.

[This message has been edited by UncleBuck (edited 12-06-2000).]

12-06-2000, 05:07 PM
Ok... well I think you miss understood me, I intend to use stencil buffer to create my shadows... but to create the shadow volume from any kind of object... Ala Quake 3...

Or, is there a way to precompute this shadow volume form abstarct mesh assuming that the light source & the objects will not be static?

12-06-2000, 05:24 PM

There is no way to pre-compute the shadow
volume if you allow your light or your
shadow caster to move or rotate, because
the silhouette will change.

However, you don't need to use the GLU
tesselators or feedback buffers. Depending
on how real you want to get, you can:

1) render your object into a texture, and
either project that texture (not really a
shadow volume) or extract edges from that
texture (make it small-ish so it's doable).
This is sort-of hard in OpenGL right now
because there's no unified support for
opening a context on texture memory as there
is in Direct3D.

2) project your object onto a flat sheet of
geometry, run duplicate-coverage removal on
that, and project from the light to make the
shadow volume (pretty good, but doesn't do
fully correct self-shadows).

3) project a shadow volume for each triangle
that faces the light (eats fill rate, but
makes for fully correct volumes).

I'm sure even smarter people than me will
come up with something that combines the
efficiency of 1) and the correctness of 3) :-)

12-07-2000, 04:26 AM
The simplest way http://www.opengl.org/discussion_boards/ubb/smile.gif is to precompute adjacency information for a given mesh - which does not have to be recomputed unless the mesh itself changes.

Then given a light vector do a dot product with each triangle in the mesh to find which triangles are lit and which are not. Then from the triangle edges which are the borders between the lit and unlit triangles you can construct your shadow volume.

I would definitely recommend you look through the MD2 shadow and bumpmapping example on nVidia's web site or Microsoft's stencil shadow volume app from it's DX8 SDK.

12-07-2000, 07:40 PM
Ok... Well I now I starting to upset you all but I reaaly want to get fixed with this...

I already got a matix with wish I project vertices on a plane, this give me the exact silhoutte of my object. Knowing those new projected points, is there a way to retrieve a strip of triangles that would produced the same silhouette without having triangles overlapping?

My shadow matrix function is :

template <class TYPE> inline CMatrix <TYPE> MVertexProjection (TYPE pA, TYPE pB, TYPE pC, TYPE pD, TYPE vX, TYPE vY, TYPE vZ, TYPE vW)
CMatrix <TYPE> temp;
TYPE Dot = pA * vX + pB * vY + pC * vZ + pD * vW;
temp.MatInd.Ind0 = Dot - vX * pA;
temp.MatInd.Ind1 = -vY * pA;
temp.MatInd.Ind2 = -vZ * pA;
temp.MatInd.Ind3 = -vW * pA;
temp.MatInd.Ind4 = -vX * pB;
temp.MatInd.Ind5 = Dot - vY * pB;
temp.MatInd.Ind6 = -vZ * pB;
temp.MatInd.Ind7 = -vW * pB;
temp.MatInd.Ind8 = -vX * pC;
temp.MatInd.Ind9 = -vY * pC;
temp.MatInd.IndA = Dot - vZ * pC;
temp.MatInd.IndB = -vW * pC;
temp.MatInd.IndC = -vX * pD;
temp.MatInd.IndD = -vY * pD;
temp.MatInd.IndE = -vZ * pD;
temp.MatInd.IndF = Dot - vW * pD;
return temp;

where MatInd is a struct of 16 TYPE element..

Thank you all...

12-08-2000, 08:06 AM
From the way you described your matrix I have a feeling you may be working towards *projected* shadows rather than shadow volumes. Projected shadows are whatare typically seen in today's games (I believe it's what Q3 uses). Projected shadows only allow you to cast onto a single flat surface (the ground place, usually), while true stencil buffer shadow volumes allow self shadowing and shadowing onto complex objects.

Anyway, in either case it sounds like what you'd like to do is extract the silhouette of the shadowing object from the point of view of the lightsource. After you have an ordered list of edge vertices you should be able to reconstruct geometry for a shadow volume, or to project onto the ground. You wouldn't have to project each triangle then. A discussion of a fast silhouette-extraction algorithm can be found in the paper "Silhouette Clipping" from SIGGRAPH 2000.

12-08-2000, 08:08 AM
You could generate an approximate shadow volume by projecting your geometry onto a plane and then doing some analysis of the resulting image, but it would be approximate.

Building your edge lists by traversing your geometry is probably the most practical way to do this.

A couple of caveats:

-- Be careful that your shadow volumes do not get clipped by the near or far clip planes

-- In the future, use of hardware-accelerated "higher order surfaces" could be severely limited, since you have to keep track of all your triangles

Shadow buffering techniques do not suffer from these issues, but unfortunately, they introduce different ones. :-)