Open risa2000 opened 5 years ago
Hi risa2000, I realise your post is about the values in the 3rd row of the matrix, related to zNear and zFar, but I noticed something I would like to check with you, although what I am saying doesn't affect the substance of your report.
You said, as the result of GetProjectionRaw for your headset:
tan_left=-1.742203, tan_right=1.346154, tan_bottom=-1.269841, tan_top=1.269841
But I am wondering if you have swapped the bottom and top values. Why I ask: there is a known issue in which the top and bottom results are swapped, which can cause a problem with headsets which have a different bottom and top tan, if the programmer isn't aware of the bug. Top results are (wrongly) returned as negative values while bottom results are positive. This inverted result seems to be subsequently cancelled out by the ComposeProjection function.
My report of the known issue, which links to two other reports: https://github.com/ValveSoftware/openvr/issues/1050
For example, with a Vive DVT, the results from GetProjectionRaw are:
eye L: Left -1.391 Right 1.254 Top -1.473 Bottom 1.466
eye R: Left -1.244 Right 1.402 Top -1.474 Bottom 1.463
@Scawen you are right, I noticed that the function declaration has top and bottom "swapped" in the header:
void GetProjectionRaw( Hmd_Eye eEye, float *pfLeft, float *pfRight, float *pfTop, float *pfBottom )
I wrote swapped because generally it is declared in the opposite order, but since I was using pyopenvr
wrapper and the values seemed to be right the other way around I assumed the Python function was returning it in the "correct" order.
And now, when looking at ComposeProjection
I realized that I also "autocorrected" the "correction" you mention, so I basically implemented: float idy = 1.0f / (fTop - fBottom);
Anyway, it seems that the doc probably needs to get some review to admit all the unexpected behavior in the first place, and then possibly correct the issue I reported.
When debugging some projection issues in a Unity game I went all the way down to OpenVR API and found this strange (and I assume wrong) behavior of
IVRSystem::GetProjectionMatrix
: (I am using Pimax 5k+ HMD andpyopenvr
to run the simple queries.)1) Unity has a function
Camera.GetStereoProjectionMatrix
, which returns this value for theleft
eye:The doc says (https://docs.unity3d.com/ScriptReference/Camera.GetStereoProjectionMatrix.html) that the value is usually provided directly by VR SDK (unless explicitly changed, which it was not).
2) OpenVR has a function
IVRSystem::GetProjectionMatrix
, which, when called on the same HMD, using the same near and far clipping planes as Unity does (near=0.1
,far=1000.1
) returns for theleft
eye this:Which is not the same matrix. Then I noticed that OpenVR has also a function which returns the "raw" values reported directly by the headset
IVRSystem::GetProjectionRaw
. Running this function for theleft
eye gives:When I run my function, which builds the projection matrix with the formulas described for example here (http://www.songho.ca/opengl/gl_projectionmatrix.html), and use "raw" values obtained above and add near and far clipping planes defined by Unity, I get the same matrix as Unity has:
On the other hand, if I take the result of
IVRSystem::GetProjectionMatrix
mentioned above and compute corresponding values forleft
,right
,bottom
,top
,near
andfar
coordinates, I get these values:Which do not correspond to the "raw" values for the near and far clipping planes.
Further, the doc page for
IVRSystem::GetProjectionRaw
(https://github.com/ValveSoftware/openvr/wiki/IVRSystem::GetProjectionRaw) suggests a functionComposeProjection
for calculating the projection matrix from the raw values, which, when implemented, gives the same wrong result as the current API.It seems that there is bug in current implementation of
IVRSystem::GetProjectionMatrix
. The correct one (usingComposeProjection
as an example) should be: