"Linear" Z-Buffer

Started by
2 comments, last by Brad Sweet 19 years, 6 months ago
Hi, My scenery presents objects with a large variation in z-distances. Consequently, I decided to convert from standard z-buffer computation to a "linear" z-buffer where, in the vertex shader, after rotation/translation, I modify the oPos.z to be: oPos.z = w * (z / (zh - zl) - zl / (zh - zl)). This seems to work great for standard rendering, BUT.... when I got around to converting my shadow-volume-extrusion-vshader (SVEV) the rendered shadows are not correct. I've stared at the code until my eyes have turned red, but to no avail. I'm confident that the zbuffer range, scale factors, matrices, etc. for the render objects and extruded vertices are consistent. I'm beginning to wonder whether this z-conversion technique is valid for shader-based shadow volume extrusions, but for-the-life-of-me, I can't understand why. Can anyone offer some insight, at least verifying whether or not this technique is robust enough to do what I'm doing? Thanks! Signed, Brad "yearning for the days of w-buffers" Sweet
Advertisement
Just a guess ... Perhaps the problem is that your shadow volume planes are not flat because the Z axis is no longer linear.

"the rendered shadows are not correct" is not much info to go on.
John BoltonLocomotive Games (THQ)Current Project: Destroy All Humans (Wii). IN STORES NOW!
it depends on how you perform the Z-test in the stencil shadow.
If you used fixed function flags then it would base the tests on the normal z-depth calculation. maybe your card is optimized for stencil shadows and does not allow modified Z values.
I'd be interested to see the source just to know whats going on.
Thanks for the timely feedback...

FYI,
The graphics card is an ATI Radeon 9800 Pro and I'm using SetRenderState( D3DRS_TWOSIDEDSTENCILMODE, TRUE ).

By the way, if I "disable" the z scaling in the following shaders, such that the h/w performs the standard z/w tests for depth comparison, the shadows look correct.

The "rendered shadows are not correct" comment is hard to articulate; mostly it appears as tho' the shadows "move" depending on camera location. I've (perhaps erroneously) chosen to debug this on a somewhat complicated scene. Perhaps I should fallback to a sphere/plane combo.

Thanks again for all help,
Brad


The standard render code (I'm currenly forcing all objects to use the same vsh):

vs_2_0
/*
diffuse.vsh
7-4-04
one directional light with normal interpolation, no specular

New Standard for Vertex Shader constants
c0-3 rotate/translate matrix
c4 Vec to lite in object space
c200 Linear Z conversion
*/

dcl_position v0
dcl_normal v1
dcl_texcoord0 v2

// rotate position into camera space
dp4 oPos.x, v0, c0
dp4 oPos.y, v0, c1
dp4 r0, v0, c2
dp4 r1, v0, c3

// c200.x = 1 / (Zh -Zl)
// c200.y = - Zl / (Zh -Zl)
mad r0.x, r0.x, c200.x, c200.y
mul r0.x, r0.x, r1.x // z*w in prep for z/w in hardware
mov oPos.z, r0.x
mov oPos.w, r1.x

mov oT0.xy, v2 // passthru vertex texture coordinates
mov oT1, v1 // load normal for interpolative normal in psh

-------------------------------------------------------------

...And the code for vertex extrusion


// c0-3 rot/translate matrix
// c4 Vec to lite in object space
// c7 0, 1, 0, ExtrusionLength

vs.2.0
dcl_position v0
dcl_normal v1

mov r1, -c4

// check normal direction, extrude if away from light
dp3 r10.w, v1, r1

// Normal faces away from light if dot result < 0.0
slt r10.x, r10.w, c7.x

// Extrude along light direction
mul r10, r10.x, c7.w
mad r4, r1, r10.x, v0
mov r4.w, c7.y // force w to 1...necessary?

// rotate position into camera space
dp4 oPos.x, r4, c0
dp4 oPos.y, r4, c1
dp4 r0, r4, c2
dp4 r1, r4, c3
mov oPos.w, r1.x

// scale z, multiply by w
// c200.x = 1 / (Zh -Zl)
// c200.y = - Zl / (Zh -Zl)
mad r0.x, r0.x, c200.x, c200.y
mul oPos.z, r0.x, r1.x // z*w in prep for z/w

This topic is closed to new replies.

Advertisement