Sign in to follow this  
Christobal_de_M

Zfail Stencil Shadows (strikes back)

Recommended Posts

Hello, I want Your opinions again. Again, I try implement Zfail shadows. Every object is casting shadow correctly (it seems to me), BUT, into shadow of current object is projecting silhouette of this object and silhouettes all other objects too. Into any stencil shadow are painting silhouettes from all objects of scene from light view point (probably). Here is some examples: http://img714.imageshack.us/gal.php?g=stencilshadowizometrie2.jpg http://img101.imageshack.us/img101/249/stencilshadowizometrie2.mp4 and here is sketch of main loop:
...
 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
 glLoadIdentity(); // .. AND OTHER TRANSFORMATION
 update_light_to_dark(); //..ONLY ONE LIGHT AND IT IS AMBIENT ONLY FOR NOW
 rendering_scene();

  //.. SHADOW PASS:
  glPushAttrib(GL_ALL_ATTRIB_BITS);
  glColorMask(0, 0, 0, 0);
  glShadeModel(GL_FLAT);
  glDepthMask(0);
  glDepthFunc(GL_LESS);
  glEnable(GL_STENCIL_TEST);

  for (every object from scene)
  {
   compute_sillhouette_and_conectivity_for_object_shadow_from_light_position(); 

   glStencilFunc(GL_ALWAYS, 0, ~0);
   glStencilOp(GL_KEEP, GL_INCR, GL_KEEP);
   glCullFace(GL_FRONT);
   object_and_shadow(); //..CAPPED SHADOW FROM OBJECT 
   glStencilOp(GL_KEEP, GL_DECR, GL_KEEP);
   glCullFace(GL_BACK);
   object_and_shadow(); //..CAPPED SHADOW FROM OBJECT 
  }
  glPopAttrib();
  //..SHADOW PASS END

  //..FINAL :
  update_light_to_normal_condition(); //..SET COMMON LIGHTING FOR SCENE 
  glStencilFunc(GL_EQUAL, 0, ~0);
  glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
  glEnable(GL_STENCIL_TEST);
  rendering_scene();
...




Thank You for Your any words about it.

Share this post


Link to post
Share on other sites
Erik Rufelt    5901
Just a guess, but seems like you don't cap the volumes properly. Do you cap both the near and far side, and have the far-plane set properly in your projection matrix so the cap isn't clipped?

Share this post


Link to post
Share on other sites
Thanks for reply. So, I do not understand in english so well, therefore, I do not understand any stencil shadow tutorial in english so well ;-). Maybe is right what You thinking.

here is source of object_and_shadow():


...
glBegin(GL_QUADS);
{
for (all faces)
{
if (face is not toward to the light) continue;
for (all vertices)
{
v1.x = obj.vertexy[obj.plochy[i].vertex_index[j]].xyzw.x;
v1.y = obj.vertexy[obj.plochy[i].vertex_index[j]].xyzw.y;
v1.z = obj.vertexy[obj.plochy[i].vertex_index[j]].xyzw.z;
v2.x = obj.vertexy[obj.plochy[i].vertex_index[(j+1)%3]].xyzw.x;
v2.y = obj.vertexy[obj.plochy[i].vertex_index[(j+1)%3]].xyzw.y;
v2.z = obj.vertexy[obj.plochy[i].vertex_index[(j+1)%3]].xyzw.z;

glVertex3f(v2.x,v2.y,v2.z);
glVertex3f(v1.x,v1.y,v1.z);
glVertex4f(v1.x-light.x,v1.y-light.y,v1.z-light.z, 0.0);
glVertex4f(v2.x-light.x,v2.y-light.y,v2.z-light.z, 0.0);
}
}
}
}
glEnd();

//Draw caps if required
if (caps)
{
glBegin(GL_TRIANGLES);
{
for (all faces)
{
for (all vertices)
{
v1.x = obj.vertexy[obj.plochy[i].vertex_index[j]].xyzw.x;
v1.y = obj.vertexy[obj.plochy[i].vertex_index[j]].xyzw.y;
v1.z = obj.vertexy[obj.plochy[i].vertex_index[j]].xyzw.z;
//.. HERE IS BOTH CAPS (?)
if (is faces toward to the light) glVertex3f(v1.x,v1.y,v1.z);
else glVertex4f(v1.x-light.x,v1.y-light.y,v1.z-light.z, 0.0);
}
}
}
glEnd();
}
...








Sorry, but I do not understand correctly about Your second idea. ,-) At the beginning in the setup OpenGL I use this :

gluPerspective(60.0, width/elevation, 0.1, 2000.0);

0.1 - is value for near clipping plane
2000.0 - is value for far clipping plane

Please, what You mean "far-plane set properly in your projection matrix" ?

And really thanks :-)

Share this post


Link to post
Share on other sites
Erik Rufelt    5901
Using glVertex4f with w = 0, the vertex is offset to infinity. Infinity is further away than the far-plane at 2000, which maybe is your problem. This can be solved with depth-clamping, not clipping but clamping depth to the far-plane. I'm not sure how this is handled by default in OpenGL, so I'm not sure if it's your problem..

If it is, another solution is to not offset to infinity, but instead to 1000 or something else that is less than 2000 (far-plane). You could do this with something like the following:

direction = v1 - light
normalize(direction)

glVertex3(v1 + direction * 1000)

Share this post


Link to post
Share on other sites
Yes, You are right. I use in my code what You was written.

direction_v1_light = vertices_1 - light_position;
direction_v1_light = normalize();
...
glVertex3f(vertices_1.x + direction_v1_light.x * 1000.0...and so on)

It is work perfect now. :-) Thank You very much for Your ideas, and thank you for Your time.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this