using UnityEngine.Rendering; namespace UnityEngine.Experimental.Rendering { /// /// Helper static class used by render pipelines to setup stereo constants accessed by builtin shaders. /// public static class XRBuiltinShaderConstants { /// /// Cached unique id for unity_StereoCameraProjection /// static public readonly int unity_StereoCameraProjection = Shader.PropertyToID("unity_StereoCameraProjection"); /// /// Cached unique id for unity_StereoCameraInvProjection /// static public readonly int unity_StereoCameraInvProjection = Shader.PropertyToID("unity_StereoCameraInvProjection"); /// /// Cached unique id for unity_StereoMatrixV /// static public readonly int unity_StereoMatrixV = Shader.PropertyToID("unity_StereoMatrixV"); /// /// Cached unique id for unity_StereoMatrixInvV /// static public readonly int unity_StereoMatrixInvV = Shader.PropertyToID("unity_StereoMatrixInvV"); /// /// Cached unique id for unity_StereoMatrixP /// static public readonly int unity_StereoMatrixP = Shader.PropertyToID("unity_StereoMatrixP"); /// /// Cached unique id for unity_StereoMatrixInvP /// static public readonly int unity_StereoMatrixInvP = Shader.PropertyToID("unity_StereoMatrixInvP"); /// /// Cached unique id for unity_StereoMatrixVP /// static public readonly int unity_StereoMatrixVP = Shader.PropertyToID("unity_StereoMatrixVP"); /// /// Cached unique id for unity_StereoMatrixInvVP /// static public readonly int unity_StereoMatrixInvVP = Shader.PropertyToID("unity_StereoMatrixInvVP"); /// /// Cached unique id for unity_StereoWorldSpaceCameraPos /// static public readonly int unity_StereoWorldSpaceCameraPos = Shader.PropertyToID("unity_StereoWorldSpaceCameraPos"); // Pre-allocate arrays to avoid GC static Matrix4x4[] s_cameraProjMatrix = new Matrix4x4[2]; static Matrix4x4[] s_invCameraProjMatrix = new Matrix4x4[2]; static Matrix4x4[] s_viewMatrix = new Matrix4x4[2]; static Matrix4x4[] s_invViewMatrix = new Matrix4x4[2]; static Matrix4x4[] s_projMatrix = new Matrix4x4[2]; static Matrix4x4[] s_invProjMatrix = new Matrix4x4[2]; static Matrix4x4[] s_viewProjMatrix = new Matrix4x4[2]; static Matrix4x4[] s_invViewProjMatrix = new Matrix4x4[2]; static Vector4[] s_worldSpaceCameraPos = new Vector4[2]; /// /// Update the shader constant data used by the C++ builtin renderer. /// /// The new view matrix that XR shaders constant should update to use. /// The new projection matrix that XR shaders constant should update to use. /// Determines the yflip state for the projection matrix. /// Index of the XR shader constant to update. public static void UpdateBuiltinShaderConstants(Matrix4x4 viewMatrix, Matrix4x4 projMatrix, bool renderIntoTexture, int viewIndex) { #if ENABLE_VR && ENABLE_XR_MODULE var gpuProjMatrix = GL.GetGPUProjectionMatrix(projMatrix, renderIntoTexture); var gpuViewProjMatrix = gpuProjMatrix * viewMatrix; s_cameraProjMatrix[viewIndex] = projMatrix; s_projMatrix[viewIndex] = gpuProjMatrix; s_viewMatrix[viewIndex] = viewMatrix; Matrix4x4.Inverse3DAffine(viewMatrix, ref s_invViewMatrix[viewIndex]); s_viewProjMatrix[viewIndex] = gpuViewProjMatrix; s_invCameraProjMatrix[viewIndex] = Matrix4x4.Inverse(projMatrix); s_invProjMatrix[viewIndex] = Matrix4x4.Inverse(gpuProjMatrix); s_invViewProjMatrix[viewIndex] = Matrix4x4.Inverse(gpuViewProjMatrix); s_worldSpaceCameraPos[viewIndex] = s_invViewMatrix[viewIndex].GetColumn(3); #endif } /// /// Bind the shader constants used by the C++ builtin renderer via a command buffer. `UpdateBuiltinShaderConstants` should be called before to update the constants. /// This is required to maintain compatibility with legacy code and shaders. /// /// Commandbuffer on which to set XR shader constants. public static void SetBuiltinShaderConstants(CommandBuffer cmd) { #if ENABLE_VR && ENABLE_XR_MODULE cmd.SetGlobalMatrixArray(unity_StereoCameraProjection, s_cameraProjMatrix); cmd.SetGlobalMatrixArray(unity_StereoCameraInvProjection, s_invCameraProjMatrix); cmd.SetGlobalMatrixArray(unity_StereoMatrixV, s_viewMatrix); cmd.SetGlobalMatrixArray(unity_StereoMatrixInvV, s_invViewMatrix); cmd.SetGlobalMatrixArray(unity_StereoMatrixP, s_projMatrix); cmd.SetGlobalMatrixArray(unity_StereoMatrixInvP, s_invProjMatrix); cmd.SetGlobalMatrixArray(unity_StereoMatrixVP, s_viewProjMatrix); cmd.SetGlobalMatrixArray(unity_StereoMatrixInvVP, s_invViewProjMatrix); cmd.SetGlobalVectorArray(unity_StereoWorldSpaceCameraPos, s_worldSpaceCameraPos); #endif } /// /// Bind the shader constants used by the C++ builtin renderer via a raster command buffer. `UpdateBuiltinShaderConstants` should be called before to update the constants. /// This is required to maintain compatibility with legacy code and shaders. /// /// RasterCommandbuffer on which to set XR shader constants. public static void SetBuiltinShaderConstants(RasterCommandBuffer cmd) { SetBuiltinShaderConstants(cmd.m_WrappedCommandBuffer); } /// /// Update and bind shader constants used by the C++ builtin renderer given the XRPass. For better control of setting up builtin shader constants, see `UpdateBuiltinShaderConstants` /// and `SetBuiltinShaderConstants` which do the same logic but could take in custom projection and view matricies instead. /// This is required to maintain compatibility with legacy code and shaders. /// /// The new XRPass that XR shader constants should update to use. /// CommandBuffer on which to set XR shader constants. /// Determines the yflip state for the projection matrix. public static void Update(XRPass xrPass, CommandBuffer cmd, bool renderIntoTexture) { #if ENABLE_VR && ENABLE_XR_MODULE if (xrPass.enabled) { cmd.SetViewProjectionMatrices(xrPass.GetViewMatrix(), xrPass.GetProjMatrix()); if (xrPass.singlePassEnabled) { for (int viewIndex = 0; viewIndex < 2; ++viewIndex) { s_cameraProjMatrix[viewIndex] = xrPass.GetProjMatrix(viewIndex); s_viewMatrix[viewIndex] = xrPass.GetViewMatrix(viewIndex); s_projMatrix[viewIndex] = GL.GetGPUProjectionMatrix(s_cameraProjMatrix[viewIndex], renderIntoTexture); s_viewProjMatrix[viewIndex] = s_projMatrix[viewIndex] * s_viewMatrix[viewIndex]; s_invCameraProjMatrix[viewIndex] = Matrix4x4.Inverse(s_cameraProjMatrix[viewIndex]); Matrix4x4.Inverse3DAffine(s_viewMatrix[viewIndex], ref s_invViewMatrix[viewIndex]); s_invProjMatrix[viewIndex] = Matrix4x4.Inverse(s_projMatrix[viewIndex]); s_invViewProjMatrix[viewIndex] = Matrix4x4.Inverse(s_viewProjMatrix[viewIndex]); s_worldSpaceCameraPos[viewIndex] = s_invViewMatrix[viewIndex].GetColumn(3); } cmd.SetGlobalMatrixArray(unity_StereoCameraProjection, s_cameraProjMatrix); cmd.SetGlobalMatrixArray(unity_StereoCameraInvProjection, s_invCameraProjMatrix); cmd.SetGlobalMatrixArray(unity_StereoMatrixV, s_viewMatrix); cmd.SetGlobalMatrixArray(unity_StereoMatrixInvV, s_invViewMatrix); cmd.SetGlobalMatrixArray(unity_StereoMatrixP, s_projMatrix); cmd.SetGlobalMatrixArray(unity_StereoMatrixInvP, s_invProjMatrix); cmd.SetGlobalMatrixArray(unity_StereoMatrixVP, s_viewProjMatrix); cmd.SetGlobalMatrixArray(unity_StereoMatrixInvVP, s_invViewProjMatrix); cmd.SetGlobalVectorArray(unity_StereoWorldSpaceCameraPos, s_worldSpaceCameraPos); } } #endif } } }