2025-12-02 16:04:23 +08:00

137 lines
5.3 KiB
C#
Raw Permalink 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 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<MeshRenderer>().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;
}
}