Projection-space vertex shader

Started by
2 comments, last by Namethatnobodyelsetook 17 years, 4 months ago
Hi all, I'm rather confused as to how the shaders work in terms of the position element. I've run into this problem multiple times so I hope you can help me. What seems logical to me is that a vertex is a 3d point in space that is projected (in the vertex shader) to screen-space, after which is it rasterized. If you would, after going to screen-space, set the .z element to '1.0f', I'd have to have the largest Z-depth value possible (screen-space projects between 0 and 1?). In practise, this doesn't work. There is a .w value that I, after many experiments and searches, still don't understand. Changing it influences objects and often just makes them disappear when I try random values. Could anybody explain the .w element to me ... or even tell me how I can give a vertex maximum z-depth within the vertex shader? I'd much appreciate any pointers, as this .w thing messed up a screen-space texture for me once. Thanks in advance, -Jeroen [Edited by - The Parrot on December 15, 2006 8:50:52 PM]
--Jeroen Stout - WebsiteCreator of-Divided
Advertisement
Quote:Original post by The Parrot
a vertex is a 3d point in space that is projected (in the vertex shader) to screen-space, after which is it rasterized.
This is probably your key misunderstanding. A vertex shader transforms to projection space - that is, between -1 and +1 independent of the real resolution.

Quote:Original post by The Parrot
If you would, after going to screen-space, set the .z element to '1.0f', I'd have to have the largest Z-depth value possible (screen-space projects between 0 and 1?).
Only depending on the current viewport description - typically this will be 0..1 but if you look through the SDK there isn't actually this as a requirement

Quote:Original post by The Parrot
There is a .w value that I, after many experiments and searches, still don't understand.
Homogenous coordinates are not trivial - I highly recommend you read Jim Blinn's Corner "A trip Down the Graphics Pipeline" - it has the single best description of W coordinates I've ever read. Basically it's a convenient mathematicaly notation that allows for various transforms and avoids various infinities and undefined results...

Your vertex shader will typically output into the -1..+1 space in XYZ and then an implicit matrix, the viewport matrix, maps this to actual pixels. Rewrite your shader accordingly...

hth
Jack

<hr align="left" width="25%" />
Jack Hoxley <small>[</small><small> Forum FAQ | Revised FAQ | MVP Profile | Developer Journal ]</small>

Quote:Original post by jollyjeffers
Quote:Original post by The Parrot
There is a .w value that I, after many experiments and searches, still don't understand.
Homogenous coordinates are not trivial - I highly recommend you read Jim Blinn's Corner "A trip Down the Graphics Pipeline" - it has the single best description of W coordinates I've ever read. Basically it's a convenient mathematicaly notation that allows for various transforms and avoids various infinities and undefined results...

Your vertex shader will typically output into the -1..+1 space in XYZ and then an implicit matrix, the viewport matrix, maps this to actual pixels. Rewrite your shader accordingly...

hth
Jack

Thanks for your reply. I know x and y in projection space are transformed between -1 and 1... I meant the 'z' value.

I'll see what I can do about the book :) and I'll clarify: 'screenspace' was badly named, I did mean projection space but messed the two up. Sorry.

Would you know any other source for explanation on the w-coördinates? I doubt I can find the book in a hurry. A brief explanation would be much appreciated; or perhaps more of a clue on my original problem: say I wanted my shader to render vertices at the maximum depth (which is 1 in my viewport setup), what would I do? Seeing as I can't change the z value; I'm stuck on how it responds to the w value.
--Jeroen Stout - WebsiteCreator of-Divided
Look at D3DXMatrixPerspectiveFovLH's docs.
When you perform a perspective matrix multiply this happens:

X = _11*pos.x + _21*pos.y + _31*pos.z + _41*pos.w;
Y = _12*pos.x + _22*pos.y + _32*pos.z + _42*pos.w;
Z = _13*pos.x + _23*pos.y + _33*pos.z + _43*pos.w;
W = _14*pos.x + _24*pos.y + _34*pos.z + _44*pos.w;

Since the W is 1 before projection, the 4th row acts as a "translation", and the first 3 rows act like a scale. We're only interested in what's going on with Z and W.

You can see W is set to 1*pos.z, so W holds your real Z value.

Z is set to scale and translate your pos.z such that
when pos.z == near, Z = 0
when pos.z == far, Z = far

After the shader, XYZ is divided by W. So, at the near plane, Z becomes (0/near, or 0), and at the far plane Z becomes (far/far, or 1).

To force a depth value of 1, set Z to W. Changing W will affect the perspective effect as XY won't divide as expected.

If you were to graph Z/W, you'll notice the value approaches 1 quickly (within the first few percent of the Z range). This gives high precision near the near plane, and poor precision further towards the far plane. The further you can push out the near plane, the better the precision at higher Z values.

This topic is closed to new replies.

Advertisement