PerspectiveFovLH mystery
Hi
I was playing around with Perspective transforms
and checking I could make the same calculations manually
but when I ran this:
Vector3 test = new Vector3(1, 1, 5);
test.TransformCoordinate(Matrix.PerspectiveFovLH(0.785f, 1.2f, 1, 10));
(fov = 0.785 45 degrees)
(aspect = 1.2)
(near = 1)
(far = 10)
it returns:
X: 0.4025955 AGREED
Y: 0.4831146 AGREED
Z: 0.8888889 SHOULD BE 0.44444!
My understanding of a perspective transform's treatment of Z values
is that it scales them from the range near->far to the range 0->1
so Z' = (Z - near) / (far - near)
which in the case above looks like:
so Z' = (5 - 1) / (10 - 1) = 0.4444444
if you look at the directx documentation it says:
w 0 0 0
0 h 0 0
0 0 zfarPlane/(zfarPlane-znearPlane) 1
0 0 -znearPlane*zfarPlane/(zfarPlane-znearPlane) 0
which means
Z' = ((5 * 10) / (10 - 1)) + ((-1 * 10)/(10 - 1)) = 0.444444
the same as my calculation
also when I use Vector3.Transform() instead it returns
W: 5.0
X: 2.01297784
Y: 2.41557336
Z: 4.44444466
which when "projected back into w=1" which I understand as divide all components by w - you get
W: 1.0
X: 0.40259558
Y: 0.4831147
Z: 0.888888955
I do not believe DirectX could be broken in this regard!
Where am I going wrong?
Quote:Original post by skytiger
My understanding of a perspective transform's treatment of Z values
is that it scales them from the range near->far to the range 0->1
so Z' = (Z - near) / (far - near)
This assumption is not correct. The mapping of Z-values from view space to post-projective space is not linear.
Also,
Quote:
if you look at the directx documentation it says:
w 0 0 0
0 h 0 0
0 0 zfarPlane/(zfarPlane-znearPlane) 1
0 0 -znearPlane*zfarPlane/(zfarPlane-znearPlane) 0
which means
Z' = ((5 * 10) / (10 - 1)) + ((-1 * 10)/(10 - 1)) = 0.444444
Correct, that's Z before you project back into w=1. Dividing by w (5 in your case), gives you Z = 0.888888955 (in NDC space), which is what the function TransformCoordinate() is giving you.
So, do you see why the D3DX functions are correct now?
[Edited by - wyrzy on March 23, 2008 6:31:13 PM]
hi
now I see
when I said:
Z' = ((5 * 10) / (10 - 1)) + ((-1 * 10)/(10 - 1)) = 0.444444
it should have read:
= 4.444444 ^
and the correct formula is:
Z' = ((far * Z - far * near) / (far - near)) / ZZ' = ((10 * 5 - 10 * 1) / (10 - 1)) / 5 = 0.8888888
but watch out!
Z' = ((10 * ? - 10 * 0) / (10 - 0)) / ? = 1
so if near plane == 0 then it does not work anymore
and everything will have a depth of 1
this game is just one brain teaser after another
:-)
[Edited by - skytiger on March 28, 2008 3:37:04 AM]
This topic is closed to new replies.
Advertisement
Popular Topics
Advertisement