- Home /
Overwrite View matrix and projection matrix in VR
I am trying to make portals (Like from the game portal). With the LWRP. I first did it for non VR, where I had RendererFeature
That would draw the scene again, but with a different View/projection matrix. I set those matrices with: CommandBuffer.SetViewProjectionMatrices(...);
. This works perfectly, but when I enabled VR and tested that. Then the projection/view matrices are just the normal ones from the camera.
Does anyone know a technique I can use to overwrite them like I did with the non-vr version?
Well it should be clear that to get the portals rendered properly you need to render your portals twice for each eye seperately since each eye has a seperate camera and therefore seperate virtual cameras for a single portal. I haven't really played around with VR and I don't have any hardware for it. So I can not help you any further at the moment.
Answer by Marco_Stone · Oct 07, 2019 at 08:10 AM
For future reference, I was using Unity 2019.2.6f1.
I saw in the Unity CG documentation that some .cginc files were automatically included, one of them was UnityShaderVariables.cginc. In that I found that unity_MatrixV
was redefined as unity_StereoMatrixV[]
:
#if defined(USING_STEREO_MATRICES)
#define glstate_matrix_projection unity_StereoMatrixP[unity_StereoEyeIndex]
#define unity_MatrixV unity_StereoMatrixV[unity_StereoEyeIndex]
#define unity_MatrixInvV unity_StereoMatrixInvV[unity_StereoEyeIndex]
#define unity_MatrixVP unity_StereoMatrixVP[unity_StereoEyeIndex]
#define unity_CameraProjection unity_StereoCameraProjection[unity_StereoEyeIndex]
#define unity_CameraInvProjection unity_StereoCameraInvProjection[unity_StereoEyeIndex]
#define unity_WorldToCamera unity_StereoWorldToCamera[unity_StereoEyeIndex]
#define unity_CameraToWorld unity_StereoCameraToWorld[unity_StereoEyeIndex]
#define _WorldSpaceCameraPos unity_StereoWorldSpaceCameraPos[unity_StereoEyeIndex]
#endif
Then lower in the file it showed where those variables were actually stored:
#if defined(USING_STEREO_MATRICES)
GLOBAL_CBUFFER_START(UnityStereoGlobals)
float4x4 unity_StereoMatrixP[2];
float4x4 unity_StereoMatrixV[2];
float4x4 unity_StereoMatrixInvV[2];
float4x4 unity_StereoMatrixVP[2];
float4x4 unity_StereoCameraProjection[2];
float4x4 unity_StereoCameraInvProjection[2];
float4x4 unity_StereoWorldToCamera[2];
float4x4 unity_StereoCameraToWorld[2];
float3 unity_StereoWorldSpaceCameraPos[2];
float4 unity_StereoScaleOffset[2];
GLOBAL_CBUFFER_END
#endif
Then I tried to use CommandBuffer.SetGlobalMatrixArray(...)
to set the array but that would not work for some reason.
The only way I found out how to override the V/P matrices for VR was to use CommandBuffer.SetGlobalConstantBuffer()
for UnityStereoGlobals. This however meant that I needed to manage all the matrices. I will put down what I know at this point:
For some reason Unity stores duplicates of the matrices. For example, unity_StereoMatrixP
is the same as unity_StereoCameraProjection
.
I believe that the Stereo projection/view matrices should be obtainable with Camera.GetStereoViewMatrix(eye)
and Camera.GetStereoProjectionMatrix(eye)
.
The unity_StereoWorldSpaceCameraPos
is as you would expect the Camera.transform.position
.
And the unity_StereoScaleOffset
is split up in 2 parts. 'xy' is the scale and 'zw' is the offset. This is different for each eye. I believe this is used to transform the UV's to be the correct uvs for the render target.
Your answer
Follow this Question
Related Questions
PBR Standard Shader not Working Project Wide in Unity 5.3 0 Answers
How can you represent overlapping energy fields? 0 Answers
Why is the CPU usage so high? 1 Answer
Render texture fullscreen on top of camera output 0 Answers
Complex Depth Shader 0 Answers