using System; using System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; using UnityEngine.XR; public class reflection : MonoBehaviour { public Camera _mainCamera; public Camera _reflectionCamera_L; public Camera _reflectionCamera_R; public Material matBur; public Transform _planner; private Material _palnnerMaterial; RenderTexture _reflectionRenderTexture_L; RenderTexture _reflectionRenderTexture_R; private int renderLeft=0; //private readonly int temp_L = Shader.PropertyToID("_reflectionRenderTexture_L"); //private readonly int temp_R = Shader.PropertyToID("_reflectionRenderTexture_R"); // Start is called before the first frame update void Start() { _reflectionCamera_L.CopyFrom(_mainCamera); _palnnerMaterial = _planner.GetComponent().material; //创建相机并指定相机渲染目标 _reflectionRenderTexture_L = new RenderTexture(Screen.width/4, Screen.height/4, 24); _reflectionCamera_L.targetTexture = _reflectionRenderTexture_L; _reflectionRenderTexture_R = new RenderTexture(Screen.width/4, Screen.height/4, 24); _reflectionCamera_R.CopyFrom(_mainCamera); _reflectionCamera_R.targetTexture = _reflectionRenderTexture_R; //将相机渲染的目标赋给材质 _palnnerMaterial.SetTexture("_ReflectionTex_R",_reflectionRenderTexture_R); _palnnerMaterial.SetTexture("_ReflectionTex_L",_reflectionRenderTexture_L); //将相机渲染的目标赋给材质 RenderPipelineManager.beginCameraRendering += OnBeginCameraRendering; } private void OnBeginCameraRendering(ScriptableRenderContext arg1, Camera arg2) { if(arg2!=_mainCamera) return; var leftEyeM = _mainCamera.GetStereoViewMatrix(Camera.StereoscopicEye.Left); var leftEyePM=_mainCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left); _reflectionCamera_L.worldToCameraMatrix =leftEyeM * CalculateReflectionCameraMatrix(Vector3.up, _planner.position); _reflectionCamera_L.projectionMatrix = leftEyePM; var rightEyeM = _mainCamera.GetStereoViewMatrix(Camera.StereoscopicEye.Right); var rightEyePM=_mainCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right); _reflectionCamera_R.worldToCameraMatrix =rightEyeM * CalculateReflectionCameraMatrix(Vector3.up, _planner.position); _reflectionCamera_R.projectionMatrix = rightEyePM; GL.invertCulling = true;//进行裁剪顺序的翻转 _palnnerMaterial.SetFloat("_renderEye",renderLeft); CommandBuffer cmd = CommandBufferPool.Get("ReflectionBur"); matBur.SetFloat("_BurStength",1f); if (renderLeft==0) { UniversalRenderPipeline.RenderSingleCamera(arg1, _reflectionCamera_L);//摄像机开始渲染 cmd.Blit(_reflectionRenderTexture_L,_reflectionRenderTexture_R,matBur,0); cmd.Blit(_reflectionRenderTexture_R,_reflectionRenderTexture_L,matBur,0); arg1.ExecuteCommandBuffer(cmd); renderLeft = 1; } else { UniversalRenderPipeline.RenderSingleCamera(arg1, _reflectionCamera_R); cmd.Blit(_reflectionRenderTexture_R,_reflectionRenderTexture_L,matBur,0); cmd.Blit(_reflectionRenderTexture_L,_reflectionRenderTexture_R,matBur,0); arg1.ExecuteCommandBuffer(cmd); renderLeft = 0; } cmd.Release(); GL.invertCulling = false;//进行裁剪顺序的翻转 } //计算反射矩阵R private Matrix4x4 CalculateReflectionCameraMatrix(Vector3 N, Vector3 plane_position)//计算返回反射矩阵 { //下面计算反射矩阵是在世界空间计算的 Matrix4x4 Reflection_camera_M = Matrix4x4.identity;//初始化反射矩阵 //d指的是平面到世界坐标原点的距离 float d = -Vector3.Dot(plane_position, N);//d = -dot(P, N),P是平面上的任意一点,N是平面的法向量 Reflection_camera_M.m00 = 1 - 2 * N.x * N.x; Reflection_camera_M.m01 = - 2 * N.x * N.y; Reflection_camera_M.m02 = - 2 * N.x * N.z; Reflection_camera_M.m03 = - 2 * N.x * d; Reflection_camera_M.m10 = - 2 * N.x * N.y; Reflection_camera_M.m11 = 1 - 2 * N.y * N.y; Reflection_camera_M.m12 = - 2 * N.y * N.z; Reflection_camera_M.m13 = - 2 * N.y * d; Reflection_camera_M.m20 = - 2 * N.x * N.z; Reflection_camera_M.m21 = - 2 * N.y * N.z; Reflection_camera_M.m22 = 1 - 2 * N.z * N.z; Reflection_camera_M.m23 = - 2 * N.z * d; Reflection_camera_M.m30 = 0; Reflection_camera_M.m31 = 0; Reflection_camera_M.m32 = 0; Reflection_camera_M.m33 = 1; return Reflection_camera_M; } private void OnDestroy() { RenderPipelineManager.beginCameraRendering -= OnBeginCameraRendering; _reflectionRenderTexture_L.Release(); _reflectionRenderTexture_R.Release(); _reflectionRenderTexture_L = null; _reflectionRenderTexture_R = null; } }