using UnityEngine; using System.Collections; using System.Collections.Generic; [ExecuteInEditMode] [RequireComponent(typeof(WaterBase))] public class PlanarReflection : MonoBehaviour { // reflection public LayerMask reflectionMask; public bool reflectSkybox = false; public Color clearColor = Color.grey; public System.String reflectionSampler = "_ReflectionTex"; // height public float clipPlaneOffset = 0.07F; private Vector3 oldpos = Vector3.zero; private Camera reflectionCamera; private Material sharedMaterial = null; private Dictionary helperCameras = null; public void Start () { sharedMaterial = ((WaterBase)gameObject.GetComponent(typeof(WaterBase))).sharedMaterial; } private Camera CreateReflectionCameraFor(Camera cam) { System.String reflName = gameObject.name+"Reflection"+cam.name; GameObject go = GameObject.Find(reflName); if(!go) go = new GameObject(reflName, typeof(Camera)); if(!go.GetComponent(typeof(Camera))) go.AddComponent(typeof(Camera)); Camera reflectCamera = go.camera; reflectCamera.backgroundColor = clearColor; reflectCamera.clearFlags = reflectSkybox ? CameraClearFlags.Skybox : CameraClearFlags.SolidColor; SetStandardCameraParameter(reflectCamera,reflectionMask); if(!reflectCamera.targetTexture) reflectCamera.targetTexture = CreateTextureFor(cam); return reflectCamera; } private void SetStandardCameraParameter(Camera cam, LayerMask mask) { cam.cullingMask = mask & ~(1<(); if(!helperCameras.ContainsKey(currentCam)) { helperCameras.Add(currentCam, false); } if(helperCameras[currentCam]) { return; } if(!reflectionCamera) reflectionCamera = CreateReflectionCameraFor(currentCam); RenderReflectionFor(currentCam, reflectionCamera); helperCameras[currentCam] = true; } public void LateUpdate () { if (null != helperCameras) helperCameras.Clear(); } public void WaterTileBeingRendered (Transform tr, Camera currentCam) { RenderHelpCameras(currentCam); if(reflectionCamera && sharedMaterial) { sharedMaterial.SetTexture(reflectionSampler, reflectionCamera.targetTexture); } } public void OnEnable() { Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_SIMPLE"); } public void OnDisable() { Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); } private void RenderReflectionFor (Camera cam, Camera reflectCamera) { if(!reflectCamera) return; if(sharedMaterial && !sharedMaterial.HasProperty(reflectionSampler)) { return; } reflectCamera.cullingMask = reflectionMask & ~(1< 0.0F) return 1.0F; if (a < 0.0F) return -1.0F; return 0.0F; } private Vector4 CameraSpacePlane (Camera cam, Vector3 pos, Vector3 normal, float sideSign) { Vector3 offsetPos = pos + normal * clipPlaneOffset; Matrix4x4 m = cam.worldToCameraMatrix; Vector3 cpos = m.MultiplyPoint (offsetPos); Vector3 cnormal = m.MultiplyVector (normal).normalized * sideSign; return new Vector4 (cnormal.x, cnormal.y, cnormal.z, -Vector3.Dot (cpos,cnormal)); } }