This topic is now archived and is closed to further replies.


I need access to the z-buffer under Direct3D 8.

Recommended Posts

For a per-pixel-computed shadow I need the depth value of every pixel, but I don''t know, how my program can get it using Direct3D 8. The driver of my Geforce 3 doesn''t support the D3DFMT_D16_LOCKABLE depth buffer format and when I use a vertex shader to copy the z-values to the color components of a image render target, component values between two vertices which should be decreased by 1.0f are iterated in negative direction. Is there another fast formula or way to get the correct per-pixel-z-values, when I have got x and y?

Share this post

Link to post
Share on other sites
const char DistanceShader[] =
"vs.1.1 \n"
"dp4 r1.x, v0, c4 \n"
"dp4 r1.y, v0, c5 \n"
"dp4 r1.z, v0, c6 \n"
"dp4 r1.w, v0, c7 \n"
"mov oPos, r1 \n"
"sub r1.z, r1.z, c8.y \n"
"mul r1.z, r1.z, c8.x \n"
"mov oD0, r1.z \n";

Where c8.y is the image plane distance and c8.x is a scaling factor

Share this post

Link to post
Share on other sites
Thanks for your effort, but the vertex shader has a huge problem: When the color component with distance value is send to the pixel pipeline, this value is converted to 8 bit. This is to few for useful calculations. I already had a shader similar to yours with some lines of code to split the float value into the RGB-components. In this way every component is blended not only from lower to higher, but also from higher to lower values. So my programm doesn''t get the correct distance for all pixels.
Is there another solution?

Share this post

Link to post
Share on other sites
Yes, that is the limitation, although I''ve found it acceptable for my needs. If you have really large distance ranges, perhaps you should use volumes? Here is a quote from Sim Dietrich at nVidia:

"You can get a higher bit depth, I have done 11 bits on GeForce1/2 & 12 bits on GeForce3. One technique I used was to do :

Create a 1024 or 2048 wide by 256 high texture.

Red Holds 8 bits of ObjectID and is a vertical ramp from 0 to 255

Green is a horizontal ramp from 0 to 255 across the texture
Blue is a series of horizontal ramps from 0 to 255, either 7 or 8 of them repeating.

Blue is the low 8 bits, Green acts as the High 3 or 4 bits.

I used the 8 bit objectID to distinguish b/t objects that didn''t intersect, and the 11 bit depth to self-shadow only. 11 bits for selfshadowing is overkill for my test objects, and can make aliasing problems worse, counterintuitively.
BTW, there is some other way to get 12 bit precision which I don''t fully understand that the MS guys talked about at GDC during their pixel shader talks. It involved overlapping the low 4 bits of red with the high 4 bits of blue, and doing the same for blue and green. Not sure if I get this one yet...

Share this post

Link to post
Share on other sites