137 lines
5.3 KiB
C#
137 lines
5.3 KiB
C#
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;
|
||
}
|
||
}
|