Sign in to follow this  

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

This topic is 2072 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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
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

This topic is 2072 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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