Sign in to follow this  
RPTD

Orthogonal Matrix Shader (or why pre-1/w fails?)

Recommended Posts

RPTD    340
I need to do a little hack to get something working. I've got a conventional projection matrix. Now I want a different way the Z values are written. For this I modified the Z-colon to reflect the changes. To avoid problems I have a vertex shader code like this:

void main( void ){
gl_Position = pMatrixMVP * vec4( inPosition, 1.0 );
gl_Position.xyw /= vec3( gl_Position.w );
}

Hence I do the perspecitive divide before sending it down to clip space but with a twist. I don't divide the Z coordinate since with my matrix modification the Z value after the transform step is already in the range -1(znear) to 1(zfar) as clip space requires it. Hence after this step gl_Position ends up with this:

gl_Position = ( x/w, y/w, z', w/w ) = ( x/z, y/z, z', 1)

where z' is the special depth value which is now in the range [-1..1]. Actually now x, y and z are in the range [-1..1] and w is 1. The perspective divide done in hardware is thus an identity projection now. Thus in clip space all values are in the range [-w..w] because w is 1 and xyz are in the range [-1..1].

The problem I have now is that the depth written out is a mess. Triangles flicker around everywhere and z is not interpolated as it should be.

I don't get why this is a problem. After all if I do a pre-multiply with 1/w this should be identical to an orthogonal matrix mapping to the range [-1..1] in all axes. Why does it still fail? Is there a way to get OGL to clip against the orthogonal matrix as I produce it above without messing up? Is there are way to make shaders work with an orthogonal matrix (after all what I produce above is an orthogonal matrix and GLSL messes up)?

Share this post


Link to post
Share on other sites
lauris71    841
Have you find a solution already?
I have seen something slightly similar, when I tried to force light volume before far clipping plane:

vClip4.z = min (vClip4.z, vClip4.w);

Now I was 100% sure that original vClipz was always > 0, but on some graphic cards (older NVidias and NVidia mobile in release build) roughly half of the screen had Z = -1 after division. On certain cards the boundary between z = 1 and z = -1 was rigged in fractal-like pattern, like there was somethng going wrong with hierarchical Z test.
I did not found better solution that to set

vClip4.z = min (vClip4.z, vClip4.w * 0.9999);

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