2025-10-09 17:36:27 +08:00

145 lines
5.8 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<ObjectVisit>();
_palnnerMaterial = _planner.GetComponent<MeshRenderer>().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;
}
}