I’m encountering an issue while working with the projection matrix in my Unity VR project. In a project using the Built-in Render Pipeline, I was able to successfully modify the projection matrices for both eyes using the code below. However, the same code doesn’t seem to work in a URP (Universal Render Pipeline) project. I’ve verified that all the functions involved are executing correctly in URP, which adds to my confusion — the new projection matrices simply don’t appear to be applied to the cameras when using URP. What’s happening?
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering;
public class ProjetctionMatrix : MonoBehaviour
{
private void Awake()
{
}
private void OnEnable()
{
RenderPipelineManager.beginFrameRendering += ScenePreCull;
}
private void OnDisable()
{
RenderPipelineManager.beginFrameRendering -= ScenePreCull;
GetComponent<Camera>().ResetStereoProjectionMatrices();
}
private void ScenePreCull(ScriptableRenderContext context, Camera[] cam)
{
OnPreCull();
}
Camera cam;
//the matrices which is going to be customized
Matrix4x4 matR, matL;
float ll, rl, bl, tl;
float lr, rr, br, tr;
float n, f;
public float gain;
public float fov_ver, fov_hor;
float v, h;
public float imageScale;
// Start is called before the first frame update
void Start()
{
cam = GetComponent<Camera>();
n = cam.nearClipPlane;
f = cam.farClipPlane;
ll = -1.349f; rl = 1.202f; tl = 1.425f; bl = -1.413f;
lr = -1.205f; rr = 1.349f; tr = 1.424f; br = -1.416f;
gain = 1f;
fov_hor = Mathf.Atan(rr) * Mathf.Rad2Deg - Mathf.Atan(ll) * Mathf.Rad2Deg;
fov_ver = Mathf.Atan(tl) * Mathf.Rad2Deg - Mathf.Atan(bl) * Mathf.Rad2Deg;
h = fov_hor;
v = fov_ver;
matR = cam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right);
matL = cam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left);
}
void Update()
{
if (Input.GetKeyDown(KeyCode.UpArrow))
gain += 0.1f;
if (Input.GetKeyDown(KeyCode.DownArrow))
gain -= 0.1f;
}
private void OnPreCull()
{
cam.ResetStereoProjectionMatrices();
newProjection(gain);
cam.SetStereoProjectionMatrix(Camera.StereoscopicEye.Right, matR);
cam.SetStereoProjectionMatrix(Camera.StereoscopicEye.Left, matL);
}
void newProjection(float gain)
{
float lR = Mathf.Tan(Mathf.Atan(lr) * gain);
float rR = Mathf.Tan(Mathf.Atan(rr) * gain);
float bR = Mathf.Tan(Mathf.Atan(br) * gain);
float tR = Mathf.Tan(Mathf.Atan(tr) * gain);
matR = Matrix4x4.Frustum(lR * n, rR * n, bR * n, tR * n, n, f);
float lL = Mathf.Tan(Mathf.Atan(ll) * gain);
float rL = Mathf.Tan(Mathf.Atan(rl) * gain);
float bL = Mathf.Tan(Mathf.Atan(bl) * gain);
float tL = Mathf.Tan(Mathf.Atan(tl) * gain);
matL = Matrix4x4.Frustum(lL * n, rL * n, bL * n, tL * n, n, f);
fov_hor = Mathf.Atan(rR) * Mathf.Rad2Deg - Mathf.Atan(lL) * Mathf.Rad2Deg;
fov_ver = Mathf.Atan(tL) * Mathf.Rad2Deg - Mathf.Atan(bL) * Mathf.Rad2Deg;
imageScale = rr / rR;
//imageScale = Mathf.Tan(v/2 * Mathf.Deg2Rad) / Mathf.Tan(fov_ver/2 * Mathf.Deg2Rad);
}
}