PDA

View Full Version : Problem with "RobustShadowVolumes"



LangFox
03-19-2002, 09:55 PM
Hi, I got the paper "RobustShadowVolumes" at developer.nvidia.com. And I tryed it, but failed. Now I post the main source code. I hope somebody can help me. Thanks.

typedef struct _TRIANGLELIST
{
ATVECTOR V[3];
GLboolean backfacing;
GLuint adjacent[3];
}TRIANGLELIST;

TRIANGLELIST trianglelist[4];

void DrawGLScene()
{
glLoadIdentity();

//1. Clear the depth buffer to 1.0; clear the color buffer.
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer

//2. Load the projection with Pinf given the aspect ratio, field of
// view, and near clip plane distance in eye-space.
GLfloat Pinf[4][4];
Pinf[1][0] = Pinf[2][0] = Pinf[3][0] = Pinf[0][1] =
Pinf[2][1] = Pinf[3][1] = Pinf[0][2] = Pinf[1][2] =
Pinf[0][3] = Pinf[1][3] = Pinf[3][3] = 0;

Pinf[0][0] = 1.0f / ((GLfloat)tan(fov) * aspect);
Pinf[1][1] = 1.0f / (GLfloat)tan(fov);
Pinf[3][2] = -2.0f * z_near; Pinf[2][2] = Pinf[2][3] = -1;

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(&Pinf[0][0]);

//3. Load the modelview matrix with the scene¡¯s viewing
// transform.
glMatrixMode(GL_MODELVIEW);
gluLookAt(m_Camera.mPosition.x, m_Camera.mPosition.y, m_Camera.mPosition.z,
m_Camera.mView.x, m_Camera.mView.y, m_Camera.mView.z,
m_Camera.mUpVector.x, m_Camera.mUpVector.y, m_Camera.mUpVector.z);

//4. Render the scene with depth testing, back-face culling, and
// all light sources disabled (ambient & emissive illumination
// only).
glEnable(GL_DEPTH_TEST); glDepthFunc(GL_LESS);
glEnable(GL_CULL_FACE); glCullFace(GL_BACK);
glEnable(GL_LIGHTING); glDisable(GL_LIGHT0);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, global_ambient);

display();

//5. Disable depth writes, enable additive blending, and set the
// global ambient light contribution to zero (and zero any
// emissive contribution if present).
glDepthMask(0);
glEnable(GL_BLEND); glBlendFunc(GL_ONE, GL_ONE);
glLightModelfv(GL_LIGHT_MODEL_AMBIENT, zero);

//6. For each light source:
// A. Clear the stencil buffer to zero.
glClear(GL_STENCIL_BUFFER_BIT);

// B. Disable color buffer writes and enable stencil testing
// with the always stencil function and writing stencil..
glColorMask(0, 0, 0, 0);
glEnable(GL_STENCIL_TEST);
glStencilFunc(GL_ALWAYS, 0, ~0); glStencilMask(~0);

// C. For each occluder:
// a. Determine whether each triangle in the occluder¡¯s
// model is front- or back-facing with respect to the
// light¡¯s position. Update triList[].backfacing.
UpdateBackfacing();

// b. Configure zfail stencil testing to increment stencil
// for back-facing polygons that fail the depth test.
glCullFace(GL_FRONT); glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);

// c. Render all possible silhouette edges as quads that
// project from the edge away from the light to
// infinity.
ATVECTOR L = ATVECTOR(light_position[0], light_position[1], light_position[2]);

glBegin(GL_QUADS);
{
for (int i = 0; i < 4; i++) // for each triangle
{
// if triangle is front-facing with respect to the light
if (!trianglelist[i].backfacing)
{
for (int j = 0; j < 3; j++) // for each triangle edge
{
// if adjacent triangle is back-facing
// with respect to the light
if (trianglelist[trianglelist[i].adjacent[j]].backfacing)
{
// found possible silhouette edge
ATVECTOR A = trianglelist[i].V[j];
ATVECTOR B = trianglelist[i].V[(j + 1) % 3]; // next vertex

glVertex4f(B.x, B.y, B.z, 1.0f);
glVertex4f(A.x, A.y, A.z, 1.0f);
glVertex4f(A.x - L.x, A.y - L.y, A.z - L.z, 0.0f); // infinite
glVertex4f(B.x - L.x, B.y - L.y, B.z - L.z, 0.0f); // infinite
}
}
}
}
}
glEnd(); // quads

// d. Specially render all occluder triangles. Project and
// render back facing triangles away from the light to
// infinity. Render front-facing triangles directly.
#define Vertex trianglelist[i].V[j] // macro used in Vertex4f calls

glBegin(GL_TRIANGLES);
{
for (int i = 0; i < 4; i++) // for each triangle
{
// if triangle is back-facing with respect to the light
if (trianglelist[i].backfacing)
for (int j = 0; j < 3; j++) // for each triangle vertex
glVertex4f(Vertex.x - L.x, Vertex.y - L.y, Vertex.z - L.z, 0); // infinite
else
for (int j = 0; j < 3; j++) // for each triangle vertex
glVertex4f(Vertex.x, Vertex.y, Vertex.z, 1.0f);
}
}
glEnd(); // triangles

// e. Configure zfail stencil testing to decrement stencil
// for front-facing polygons that fail the depth test.
glCullFace(GL_BACK); glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);

// f. Repeat steps (c) and (d) above, this time rendering
// front facing polygons rather than back facing ones.
glBegin(GL_QUADS);
{
for (int i = 0; i < 4; i++) // for each triangle
{
// if triangle is front-facing with respect to the light
if (!trianglelist[i].backfacing)
{
for (int j = 0; j < 3; j++) // for each triangle edge
{
// if adjacent triangle is back-facing
// with respect to the light
if (trianglelist[trianglelist[i].adjacent[j]].backfacing)
{
// found possible silhouette edge
ATVECTOR A = trianglelist[i].V[j];
ATVECTOR B = trianglelist[i].V[(j + 1) % 3]; // next vertex

glVertex4f(B.x, B.y, B.z, 1.0f);
glVertex4f(A.x, A.y, A.z, 1.0f);
glVertex4f(A.x - L.x, A.y - L.y, A.z - L.z, 0.0f); // infinite
glVertex4f(B.x - L.x, B.y - L.y, B.z - L.z, 0.0f); // infinite
}
}
}
}
}
glEnd(); // quads

glBegin(GL_TRIANGLES);
{
for (int i = 0; i < 4; i++) // for each triangle
{
// if triangle is back-facing with respect to the light
if (trianglelist[i].backfacing)
for (int j = 0; j < 3; j++) // for each triangle vertex
glVertex4f(Vertex.x - L.x, Vertex.y - L.y, Vertex.z - L.z, 0); // infinite
else
for (int j = 0; j < 3; j++) // for each triangle vertex
glVertex4f(Vertex.x, Vertex.y, Vertex.z, 1.0f);
}
}
glEnd(); // triangles

//D. Position and enable the current light (and otherwise
// configure the light¡¯s attenuation, color, etc.).
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_POSITION, light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);

//E. Set stencil testing to render only pixels with a zero
// stencil value, i.e., visible fragments illuminated by the
// current light. Use equal depth testing to update only the
// visible fragments, and then, increment stencil to avoid
// double blending. Re-enable color buffer writes again.
glStencilFunc(GL_EQUAL, 0, ~0); glStencilOp(GL_KEEP, GL_KEEP, GL_INCR);
glDepthFunc(GL_EQUAL); glColorMask(1,1,1,1);

//F. Re-draw the scene to add the contribution of the current
// light to illuminated (non-shadowed) regions of the
// scene.
display();

// G. Restore the depth test to less.
glDepthFunc(GL_LESS);

//7. Disable blending and stencil testing; re-enable depth writes.
glDisable(GL_BLEND); glDisable(GL_STENCIL_TEST); glDepthMask(1);
...
}

cass
03-20-2002, 06:45 AM
Hi LangFox,

I am at GDC right now and I don't have time to study your code, but we should be posting a couple of demos that implement the technique soon.

Unfortunately, I go on vacation for a week after GDC so it'll be April for at least one of the demos. {Mark K may be able to get his "postworthy" before then.}

Thanks -
Cass

NitroGL
03-20-2002, 09:35 AM
Originally posted by cass:
Hi LangFox,

I am at GDC right now and I don't have time to study your code, but we should be posting a couple of demos that implement the technique soon.

Unfortunately, I go on vacation for a week after GDC so it'll be April for at least one of the demos. {Mark K may be able to get his "postworthy" before then.}

Thanks -
Cass

I hope these demos won't use some silly nVidia proprietary extension. http://www.opengl.org/discussion_boards/ubb/rolleyes.gif

SnowKrash
03-20-2002, 10:21 AM
for (int j = 0; j < 3; j++) // for each triangle vertex
glVertex4f(Vertex.x - L.x, Vertex.y - L.y, Vertex.z - L.z, 0); // infinite

I'm pretty sure you should be drawing the infinite capping faces in reverse winding order, ie (int j = 2; j >= 0; j--)

Update: I read the paper again and forgot that I was doing things differently in my implementation due to working with open models. Rather than using back faces I reverse the front faces.

Disclaimer: I'm a newbie poster here and can't seem use codes - so many edits

[This message has been edited by SnowKrash (edited 03-20-2002).]

[This message has been edited by SnowKrash (edited 03-20-2002).]

LangFox
03-20-2002, 04:09 PM
All right!
Thank you everyone.