views:

45

answers:

2

Hello, I'm trying to do the following technique for shadowing, I read it on the NVIDIA site and it seemed like a good technique. I would prefer it to calculating shadow volumes on the cpu because it seems more 'true' and I could use this one for soft-shadowing. :

1st pass:

  • Fill depth buffer from perspective of LIGHT0. Copy this depth buffer for second pass. (*)

2nd pass:

  • Render view from EYE, and for each fragment:
    • Get the XY location in the depth buffer stored in (*). Get the corresponding 32-bit value.
    • Calculate the distance to the light.
    • Match this distance to the stored depth buffer value.
    • If it is larger, then the fragment is drawn in glDisable(LIGHT0) mode, otherwise it is drawn with the light enabled. For this purpose I use two fragment shaders and fragments blend/switch between the two according to the comparison of the distance.

Now, I'd want to do the last steps in the fragment shader, for some reasons. One of them is that I want to take the distance into account for the 'effect" of the shadowing. In my game, if the distance to the obstructing object is small, it is safe to say that the shadow will be very "strict". If it is further away, global illumination kicks in more and the shadow is slighter. This is because it's a card game, this would not be the case for more complicated 'concave' shapes.

But, I'm new to openGL and I don't understand how to do any of the following:

  • How to access that 1st pass depth buffer in the fragment shader without copying it to a 2d texture. I assume that is not possible?
  • If copying the 32-bit depth buffer to a texture that has 8-bits in each R,G,B,A component and then re-assembling that value in the fragment shader is the most efficient thing I can do?
  • If there are cross-platform extensions I could use for this.

Thanks if someone can help me or give me some more ideas, I'm kind of stumped right now and my lack of good hardware and free time really makes for an exhausting process to debug/try everything out.

A: 

You are right: you need to create a 2D texture from the depth buffer values in order to use those values in the 2nd pass.

Concerning the texture itself, I think that copying from 32bits depth buffer to 8 bits RGBA will not use a cast to convert data: for a mid range value of the depth buffer (say 0x80000000), you will get half tone on R, G, B and A on your rgba texture:

RGBA[0] = 0x80;
RGBA[1] = 0x80;
RGBA[2] = 0x80;
RGBA[3] = 0x80;

Where you would have expected: (cast)

RGBA[0] = 0x80;
RGBA[1] = 0;
RGBA[2] = 0;
RGBA[3] = 0;

So, for the right format, I am not sure, but I would suggest you not to modify it during the copy, since you don't want to have a conversion overhead.

tibur
+1  A: 

1st way is to use FBOs with a GL_DEPTH_COMPONENT texture attached to the GL_DEPTH_ATTACHMENT attachment.

The second way is to use glCopyTexImage2D again with a GL_DEPTH_COMPONENT texture.

FBOs are cross platform and available in almost every modern OpenGL implementation, you should have them available to you.

Matias Valdenegro