using System; using System.Collections; using System.Collections.Generic; using Unity.VisualScripting; using UnityEngine; using UnityEngine.Rendering; using UnityEngine.Rendering.Universal; using UnityEngine.UIElements; 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 ObjectVisit visit; // Start is called before the first frame update void Start() { visit=_planner.AddComponent(); _palnnerMaterial = _planner.GetComponent().material; _reflectionCamera_L.CopyFrom(_mainCamera); _reflectionCamera_L.clearFlags = CameraClearFlags.Color; _reflectionCamera_L.backgroundColor=Color.black; _reflectionCamera_L.allowMSAA = false; //创建相机并指定相机渲染目标 _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.clearFlags = CameraClearFlags.Color; _reflectionCamera_R.backgroundColor=Color.black; _reflectionCamera_R.allowMSAA = false; _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 || visit.isVisit==false) return; visit.isVisit = false; _palnnerMaterial.SetFloat("_renderEye",renderLeft); CommandBuffer cmd = CommandBufferPool.Get("ReflectionBur"); matBur.SetFloat("_BurStength",1f); if (renderLeft==0) { Matrix4x4 leftEyeM = _mainCamera.GetStereoViewMatrix(Camera.StereoscopicEye.Left); Matrix4x4 leftEyePM=_mainCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left); _reflectionCamera_L.worldToCameraMatrix =leftEyeM * CalculateReflectionCameraMatrix(Vector3.up, _planner.position); _reflectionCamera_L.projectionMatrix = leftEyePM; GL.invertCulling = true;//进行裁剪顺序的翻转 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; GL.invertCulling = false;//进行裁剪顺序的翻转 } else { Matrix4x4 rightEyeM = _mainCamera.GetStereoViewMatrix(Camera.StereoscopicEye.Right); Matrix4x4 rightEyePM=_mainCamera.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right); _reflectionCamera_R.worldToCameraMatrix =rightEyeM * CalculateReflectionCameraMatrix(Vector3.up, _planner.position); _reflectionCamera_R.projectionMatrix = rightEyePM; GL.invertCulling = true;//进行裁剪顺序的翻转 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; GL.invertCulling = false;//进行裁剪顺序的翻转 } CommandBufferPool.Release(cmd); } //计算反射矩阵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; Destroy(visit); _reflectionRenderTexture_L.Release(); _reflectionRenderTexture_R.Release(); _reflectionRenderTexture_L = null; _reflectionRenderTexture_R = null; } }