# Projection Matrix Effect

## Recommended Posts

Kest    547
This could have been posted in graphics programming, directX, or math, but I'm choosing math because of the levels of sentience in here. I've only used one type of matrix row/column setup, and I'm not sure of their individual titles. But the matrix I use is set up like this:
R = Right
U = Up
F = Forward
T = Translation

R.x R.y R.z 0
U.x U.y U.z 0
F.x F.y F.z 0
T.x T.y T.z 1

My normal projection matrix is constructed in this way:
float aspect = ScreenWidth / ScreenHeight;
float w = cosf( FOV / 2 ) / sinf( FOV / 2 );
float h = w * aspect;

float ff = FarPlaneDistance / ( FarPlaneDistance - NearPlaneDistance );
float tf = -ff * NearPlaneDistance;

Matrix:
w  0  0  0
0  h  0  0
0  0  ff 1
0  0  tf 0

My goal is to render something, something that is in normal world-space, and has a normal world-space transform matrix, but to have it write the highest z-buffer values possible to the depth buffer. After playing around a little, I've come up with this projection matrix:
float aspect = ScreenWidth / ScreenHeight;
float w = cosf( FOV / 2 ) / sinf( FOV / 2 );
float h = w * aspect;

Matrix:
w  0  0  0
0  h  0  0
0  0  1  1
0  0  0  0

I don't completely understand what effect this is having. But if I disable z-testing (disable z-reading, but leave z-writing on), it seems to render the object at really high z values (I'm guessing >= 0.99, maybe even 1.0), no matter where it actually is on the screen. Another thing I really liked was the fact that the object is never clipped when it gets really far away. In my vertex shader, vertices are mutlipied by [world_matrix * view_matrix * proj_matrix]. If I were to guess, I would say that FF->1 is a z scaler, which is scaling rendered objects throughout the entire z distance with a value of 1. And that TF->0 is the z translation, where 0 is forcing objects to appear as though they are smashed onto the screen. Is this way off? I'm interested in understanding this better. And most importantly, knowing about any problems I could run into with other graphics cards or drivers. Thanks for any help!

##### Share on other sites
Zipster    2365
FF and TF perform a linear transformation on z, such that z' = FF*z + TF. The hardware then performs a homogeneous divide, where [x y z w] becomes [x/w y/w z/w 1] and the final 1 is ignored. Since the projection matrix usually sets w to be the value of z, after this divide the final z-value is z" = (FF*z + TF)/z, which can be re-written as z" = TF/z + FF, which is an inverse-linear function. However if you let TF = 0 and FF = 1, then z" is always 1, which is the farthest depth. You can see then how in a normal projection matrix, TF and FF are set such than when z is the far plane, z" is 1, and when z is the near plane, z" is 0.

Kest    547