using System; using UnityEngine; public class Mirror_2DandOculus : MonoBehaviour { private void Start() { this.m_My_Render = base.GetComponent(); this.m_My_Render.sharedMaterial.shader = Resources.Load("Shaders/Mirror_2DandOculus"); int antiAliasing = (QualitySettings.antiAliasing != 0) ? QualitySettings.antiAliasing : 1; this.m_Reflect_Texture = new RenderTexture(this.m_TextureSize, this.m_TextureSize, 16); this.m_Reflect_Texture.name = "_MirrorTexture"; this.m_Reflect_Texture.isPowerOfTwo = true; this.m_Reflect_Texture.antiAliasing = antiAliasing; this.CreateMirrorObjects(); } private void OnWillRenderObject() { if (this.m_SelfRendering) { return; } if (SteamVR.instance != null) { base.enabled = false; return; } this.m_SelfRendering = true; this.Reflection(Camera.current, this.m_Reflect_Texture); this.m_SelfRendering = false; } private void Reflection(Camera current_cam, RenderTexture reflect_Tex) { Vector3 position = base.transform.position; Vector3 vector = base.transform.TransformDirection(Vector3.back); this.UpdateCameraModes(current_cam, this.m_Reflect_Camera); float w = -Vector3.Dot(vector, position) - this.m_ClipPlaneOffset; Vector4 plane = new Vector4(vector.x, vector.y, vector.z, w); Matrix4x4 zero = Matrix4x4.zero; this.CalculateReflectionMatrix(ref zero, plane); Vector3 position2 = Camera.current.transform.position; Vector3 position3 = zero.MultiplyPoint(position2); this.m_Reflect_Camera.transform.position = position3; Vector3 eulerAngles = Camera.current.transform.eulerAngles; this.m_Reflect_Camera.transform.eulerAngles = eulerAngles; this.m_Reflect_Camera.worldToCameraMatrix = current_cam.worldToCameraMatrix * zero; Vector4 clipPlane = this.CameraSpacePlane(this.m_Reflect_Camera, position, vector, 1f); Matrix4x4 projectionMatrix = current_cam.CalculateObliqueMatrix(clipPlane); this.m_Reflect_Camera.projectionMatrix = projectionMatrix; this.m_Reflect_Camera.cullingMask = this.m_ReflectLayers.value; GL.invertCulling = true; this.m_Reflect_Camera.targetTexture = reflect_Tex; this.m_Reflect_Camera.Render(); this.m_My_Render.sharedMaterial.SetTexture("_MainTex", reflect_Tex); GL.invertCulling = false; } private void UpdateCameraModes(Camera src, Camera dest) { if (dest == null) { return; } dest.clearFlags = src.clearFlags; dest.backgroundColor = src.backgroundColor; dest.farClipPlane = src.farClipPlane; dest.nearClipPlane = src.nearClipPlane; dest.orthographic = src.orthographic; dest.fieldOfView = src.fieldOfView; dest.aspect = src.aspect; dest.orthographicSize = src.orthographicSize; } private void CreateMirrorObjects() { GameObject gameObject = new GameObject("Mirror Refl Camera", new Type[] { typeof(Camera) }); this.m_Reflect_Camera = gameObject.GetComponent(); this.m_Reflect_Camera.enabled = false; this.m_Reflect_Camera.transform.position = base.transform.position; this.m_Reflect_Camera.transform.rotation = base.transform.rotation; gameObject.transform.parent = base.transform; } private Vector4 CameraSpacePlane(Camera cam, Vector3 pos, Vector3 normal, float sideSign) { Vector3 v = pos + normal * this.m_ClipPlaneOffset; Matrix4x4 worldToCameraMatrix = cam.worldToCameraMatrix; Vector3 lhs = worldToCameraMatrix.MultiplyPoint(v); Vector3 rhs = worldToCameraMatrix.MultiplyVector(normal).normalized * sideSign; return new Vector4(rhs.x, rhs.y, rhs.z, -Vector3.Dot(lhs, rhs)); } private void CalculateReflectionMatrix(ref Matrix4x4 reflectionMat, Vector4 plane) { reflectionMat.m00 = 1f - 2f * plane[0] * plane[0]; reflectionMat.m01 = -2f * plane[0] * plane[1]; reflectionMat.m02 = -2f * plane[0] * plane[2]; reflectionMat.m03 = -2f * plane[3] * plane[0]; reflectionMat.m10 = -2f * plane[1] * plane[0]; reflectionMat.m11 = 1f - 2f * plane[1] * plane[1]; reflectionMat.m12 = -2f * plane[1] * plane[2]; reflectionMat.m13 = -2f * plane[3] * plane[1]; reflectionMat.m20 = -2f * plane[2] * plane[0]; reflectionMat.m21 = -2f * plane[2] * plane[1]; reflectionMat.m22 = 1f - 2f * plane[2] * plane[2]; reflectionMat.m23 = -2f * plane[3] * plane[2]; reflectionMat.m30 = 0f; reflectionMat.m31 = 0f; reflectionMat.m32 = 0f; reflectionMat.m33 = 1f; } private const string m_Shader_Path = "Shaders/Mirror_2DandOculus"; [SerializeField] private int m_TextureSize = 2048; [SerializeField] private float m_ClipPlaneOffset = 0.07f; [SerializeField] private LayerMask m_ReflectLayers = -1; private bool m_SelfRendering; private Renderer m_My_Render; private Camera m_Reflect_Camera; private RenderTexture m_Reflect_Texture; }