Unity3d mirror reflection
What can be found on the Internet is basically a fixed pipe or a shader for surface rendering,
We hereby translate the Shader for vertex and fragment rendering,
This source code only involves the shader and cs sections,
The Editor is drawn using NGUI,
Download NGUI
Unity3d version: v4.3.1
ReflectionMirror. cs
Using UnityEngine; using System. collections; using System; /// <summary> // Reflection effect // </summary> [AddComponentMenu ("GameCore/SpecialEffect/Reflection Mirror")] [ExecuteInEditMode] public class ReflectionMirror: MonoBehaviour {public bool Limit = true; public int TextureSize = 512; public float ClipPlaneOffset = 0; public LayerMask ReflectLayers =-1; hasprivate htable Limit = ne W Hashtable (); // Camera-> Camera table private RenderTexture m_ReflectionTexture = null; private int m_OldReflectionTextureSize = 0; private static bool s_InsideRendering = false; // This is called when it's known that the object will be rendered by some // camera. we render reflections and do other updates here. // Because the script executes in edit mode, reflections for the scene view // came Ra will just work! Public void OnWillRenderObject () {if (! Enabled |! Renderer |! Renderer. sharedMaterial |! Renderer. enabled) return; Camera cam = Camera. current; if (! Cam) return; // Safeguard from recursive reflections. if (s_InsideRendering) return; s_InsideRendering = true; Camera reflectionCamera; Camera (cam, out reflectionCamera); // find out the reflection plane: position and normal in world space Vector3 pos = transform. position; Vector3 normal = transform. up; // Optionally disable pixel lights for reflection int oldPixelLightCount = QualityS Ettings. pixelLightCount; if (DisablePixelLights) QualitySettings. pixelLightCount = 0; CoreTool. rotate (cam, reflectionCamera); // Render reflection // Reflect camera around reflection plane float d =-Vector3.Dot (normal, pos)-ClipPlaneOffset; Vector4 reflectionPlane = new Vector4 (normal. x, normal. y, normal. z, d); Matrix4x4 reflection = CoreTool. calculateReflectionMatrix (Matrix4x4. zero, ReflectionPlane); Vector3 oldpos = cam. transform. position; Vector3 newpos = reflection. multiplyPoint (oldpos); reflectionCamera. worldToCameraMatrix = cam. worldToCameraMatrix * reflection; // Setup oblique projection matrix so that near plane is our reflection // plane. this way we clip everything below/above it for free. vector4 clipPlane = CoreTool. cameraSpacePlane (reflectionCamera, pos, normal, 1. 0f, ClipPlaneOffset); Matrix4x4 projection = cam. projectionMatrix; projection = CoreTool. Partition (projection, clipPlane); reflectionCamera. projectionMatrix = projection; reflectionCamera. cullingMask = ~ (1 <4) & ReflectLayers. value; // never render water layer reflectionCamera.tar getTexture = m_ReflectionTexture; GL. setRevertBackfacing (true); reflectionCamera. transform. position = newpos; Vector3 euler = cam. transform. eulerAngles; reflectionCamera. transform. eulerAngles = new Vector3 (0, euler. y, euler. z); reflectionCamera. render (); reflectionCamera. transform. position = oldpos; GL. setRevertBackfaci Ng (false); Material [] materials = renderer. sharedMaterials; foreach (Material mat in materials) {if (mat. hasProperty ("_ ReflectionTex") mat. setTexture ("_ ReflectionTex", m_ReflectionTexture);} // Set matrix on the shader that transforms UVs from object space into screen // space. we want to just project reflection texture on screen. matrix4x4 scaleOffset = Matrix4x4. TRS (new Vector3 (0.5f, 0.5f, 0. 5f), Quaternion. identity, new Vector3 (0.5f, 0.5f, 0.5f); Vector3 scale = transform. lossyScale; Matrix4x4 xr = transform. localToWorldMatrix * Matrix4x4. scale (new Vector3 (1.0f/scale. x, 1.0f/scale. y, 1.0f/scale. z); SVD = scaleOffset * cam. projectionMatrix * cam. worldToCameraMatrix * CTX; foreach (Material mat in materials) {mat. setMatrix ("_ ProjMatrix", CTX);} // Restore pixel light count If (DisablePixelLights) QualitySettings. pixelLightCount = upper; lower = false;} // Cleanup all the objects we possibly have created void OnDisable () {if (m_ReflectionTexture) {lower (m_ReflectionTexture); m_ReflectionTexture = null ;} foreach (DictionaryEntry kvp in m_ReflectionCameras) DestroyImmediate (Camera) kvp. value ). gameObject); m_ReflectionCameras.Cle Ar ();} // On-demand create any objects we need private void CreateMirrorObjects (Camera currentCamera, out Camera reflectionCamera) {reflectionCamera = null; // Reflection render texture if (! M_ReflectionTexture | m_OldReflectionTextureSize! = TextureSize) {if (m_ReflectionTexture) Then (m_ReflectionTexture); then = new RenderTexture (TextureSize, TextureSize, 0); then = "_ MirrorReflection" + GetInstanceID (); m_ReflectionTexture.isPowerOfTwo = true; m_ReflectionTexture.hideFlags = HideFlags. dontSave; m_ReflectionTexture.antiAliasing = 4; m_ReflectionTexture.anisoLevel = 0; m_OldReflectionTe XtureSize = TextureSize;} // Camera for reflection reflectionCamera = m_ReflectionCameras [currentCamera] as Camera; if (! ReflectionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO {GameObject go = new GameObject ("Mirror Refl Camera id" + GetInstanceID () + "for" + currentCamera. getInstanceID (), typeof (Camera), typeof (Skybox); reflectionCamera = go. camera; reflectionCamera. enabled = false; reflectionCamera. transform. position = transform. position; reflectionCamera. transform. rotation = transform. rotation; reflectionCamera. gameObject. addComponent ("FlareLayer"); go. hideFlags = HideFlags. hideAndDontSave; m_ReflectionCameras [currentCamera] = reflectionCamera ;}}}
ReflectionMirrorEditor. cs
Using System. collections; using System; using UnityEditor; using UnityEngine; // <summary> // reflection effect /// </summary> [CustomEditor (typeof (ReflectionMirror)] public class ReflectionMirrorEditor: Editor {string [] _ renderTextureOptions = new string [8] {"16", "32", "64", "128", "256 ", "512", "1024", "2048"}; int _ renderTextureWidthDefaultIndex = 5; int _ renderTextureWidthIndex = 5; SerializedProperty _ sp; p Ublic override void OnInspectorGUI () {EditorGUILayout. HelpBox ("This the reflection effect, it has mirror or sphere reflection! ", MessageType. info); if (NGUIEditorTools. drawHeader ("Reflection Settings") {NGUIEditorTools. beginContents (); {NGUIEditorTools. drawProperty ("Disable PixelLights", this. serializedObject, "DisablePixelLights"); NGUIEditorTools. drawProperty ("Reflect Layers", this. serializedObject, "ReflectLayers"); NGUIEditorTools. drawProperty ("ClipPlane Offset", this. serializedObject, "ClipPlaneOffset");} NGUIEditorTools. endContents ();} if (NGUIEditorTools. drawHeader ("Render Texture Settings") {NGUIEditorTools. beginContents (); {_ sp = this. serializedObject. findProperty ("TextureSize"); _ renderTextureWidthIndex = GetTextureOptionsIndex (_ sp. intValue. toString (); EditorGUILayout. beginHorizontal (); EditorGUILayout. labelField ("TexSize:", GUILayout. width (100); _ renderTextureWidthIndex = EditorGUILayout. popup (_ renderTextureWidthIndex, _ renderTextureOptions); EditorGUILayout. endHorizontal (); if (GUILayout. button ("Make Default Value") {_ renderTextureWidthIndex = _ renderTextureWidthDefaultIndex;} _ sp. intValue = int. parse (_ renderTextureOptions [_ renderTextureWidthIndex]);} NGUIEditorTools. endContents ();} this. serializedObject. applyModifiedProperties ();} int GetTextureOptionsIndex (string value) {int index = 0; for (int I = 0; I <_ renderTextureOptions. length; I ++) {if (_ renderTextureOptions [I]. equals (value, StringComparison. ordinalIgnoreCase) {index = I ;}} return index ;}}
Shader
Shader "GameCore/SpecialEffect/Reflection Mirror"{ Properties { _ReflectionTex ("Reflection", 2D) = "white" {TexGen ObjectLinear }_ReflectionColor("Color",Color) = (1,1,1,1)}//PCSubShader { Tags { "RenderType"="Opaque"}LOD 100Pass { CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"uniform float4x4 _ProjMatrix; uniform sampler2D _ReflectionTex; float4 _ReflectionColor; struct outvertex { float4 pos : SV_POSITION; float3 uv : TEXCOORD0; }; outvertex vert(appdata_tan v) { outvertex o; o.pos = mul (UNITY_MATRIX_MVP,v.vertex); float3 viewDir = ObjSpaceViewDir(v.vertex);o.uv = mul(_ProjMatrix,float4(viewDir,0));return o; }float4 frag(outvertex i) : COLOR { half4 reflcol = tex2Dproj(_ReflectionTex,i.uv); return reflcol*_ReflectionColor; }ENDCG}}//MobileSubShader { Tags { "RenderType"="Opaque"}LOD 100Pass { CGPROGRAM#pragma vertex vert#pragma fragment frag#include "UnityCG.cginc"uniform float4x4 _ProjMatrix; uniform sampler2D _ReflectionTex; float4 _ReflectionColor; struct outvertex { float4 pos : SV_POSITION; float3 uv : TEXCOORD0; float4 posProj; }; outvertex vert(appdata_tan v) { outvertex o; o.pos = mul (UNITY_MATRIX_MVP,v.vertex); o.posProj = mul(_ProjMatrix, v.vertex); return o; }float4 frag(outvertex i) : COLOR { half4 reflcol = tex2D(_ReflectionTex,float2(i.posProj) / i.posProj.w); return reflcol*_ReflectionColor; }ENDCG}}}
Source code link: http://pan.baidu.com/s/1gdyzyNL