private void Awake() { m_material = GetComponent <Renderer>().sharedMaterial; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); //m_waterMode = GetWaterMode (); m_waveSpeed = m_material.GetVector("WaveSpeed"); m_waveScale = m_material.GetFloat("_WaveScale"); m_waveScale4 = new Vector4(m_waveScale, m_waveScale, m_waveScale * 0.4f, m_waveScale * 0.45f); m_material.SetVector("_WaveScale4", m_waveScale4); m_xWaveSpeedScaled = m_waveSpeed.x * m_waveScale4.x; m_yWaveSpeedScaled = m_waveSpeed.y * m_waveScale4.y; m_zWaveSpeedScaled = m_waveSpeed.z * m_waveScale4.z; m_wWaveSpeedScaled = m_waveSpeed.w * m_waveScale4.w; m_camera = Camera.current; // CreateWaterObjects (m_camera, out m_reflectionCamera, out m_refractionCamera); // UpdateCameraModes (m_camera, m_reflectionCamera); // UpdateCameraModes (m_camera, m_refractionCamera); }
// This just sets up some matrices in the material; for really // old cards to make water texture scroll. void Update() { WaterMode mode = GetWaterMode(); if (mode != WaterMode.Cube) { if (waterMaterials.Length <= 0) { return; } float waveScale = waterMaterials[0].GetFloat("_WaveScale"); Vector4 waveScale4 = new Vector4(waveScale, waveScale, waveScale * 0.4f, waveScale * 0.45f); waterMaterials[0].SetVector("_WaveScale4", waveScale4); if (waterMaterials.Length > 1) { waterMaterials[1].SetVector("_WaveScale4", waveScale4); } if (mode != WaterMode.Simple) { Vector4 waveSpeed = waterMaterials[0].GetVector("WaveSpeed"); // Time since level load, and do intermediate calculations with doubles double t = Time.timeSinceLevelLoad / 20.0; Vector4 offsetClamped = new Vector4( (float)System.Math.IEEERemainder(waveSpeed.x * waveScale4.x * t, 1.0), (float)System.Math.IEEERemainder(waveSpeed.y * waveScale4.y * t, 1.0), (float)System.Math.IEEERemainder(waveSpeed.z * waveScale4.z * t, 1.0), (float)System.Math.IEEERemainder(waveSpeed.w * waveScale4.w * t, 1.0) ); waterMaterials[0].SetVector("_WaveOffset", offsetClamped); if (waterMaterials.Length > 1) { waterMaterials[1].SetVector("_WaveOffset", offsetClamped); waterMaterials[1].SetVector("_WaveScale4", waveScale4); float reflectionDistort = waterMaterials[0].GetFloat("_ReflDistort"); float refractionDistort = waterMaterials[0].GetFloat("_RefrDistort"); waterMaterials[1].SetFloat("_ReflDistort", reflectionDistort); waterMaterials[1].SetFloat("_RefrDistort", refractionDistort); } Vector3 waterSize = waterRenderer.bounds.size; Vector3 scale = new Vector3(waterSize.x * waveScale4.x, waterSize.z * waveScale4.y, 1); Matrix4x4 scrollMatrix = Matrix4x4.TRS(new Vector3(offsetClamped.x, offsetClamped.y, 0), Quaternion.identity, scale); waterMaterials[0].SetMatrix("_WaveMatrix", scrollMatrix); if (waterMaterials.Length > 1) { waterMaterials[1].SetMatrix("_WaveMatrix", scrollMatrix); } scale = new Vector3(waterSize.x * waveScale4.z, waterSize.z * waveScale4.w, 1); scrollMatrix = Matrix4x4.TRS(new Vector3(offsetClamped.z, offsetClamped.w, 0), Quaternion.identity, scale); waterMaterials[0].SetMatrix("_WaveMatrix2", scrollMatrix); if (waterMaterials.Length > 1) { waterMaterials[1].SetMatrix("_WaveMatrix2", scrollMatrix); } } } }
// On-demand create any objects we need for water private void CreateWaterObjects(Camera currentCamera, out Camera reflectionCamera) { WaterMode mode = GetWaterMode(); reflectionCamera = null; if (mode >= WaterMode.Reflective) { // Reflection render texture if (!m_ReflectionTexture || m_OldReflectionTextureSize != m_TextureSize) { if (m_ReflectionTexture) { DestroyImmediate(m_ReflectionTexture); } m_ReflectionTexture = new RenderTexture(m_TextureSize, m_TextureSize, 16); m_ReflectionTexture.name = "__WaterReflection" + GetInstanceID(); m_ReflectionTexture.isPowerOfTwo = true; m_ReflectionTexture.hideFlags = HideFlags.DontSave; m_OldReflectionTextureSize = m_TextureSize; } // Camera for reflection m_ReflectionCameras.TryGetValue(currentCamera, out reflectionCamera); if (!reflectionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO { GameObject go = new GameObject("Water Refl Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox)); reflectionCamera = go.GetComponent <Camera>(); reflectionCamera.enabled = false; reflectionCamera.transform.position = transform.position; reflectionCamera.transform.rotation = transform.rotation; reflectionCamera.gameObject.AddComponent <FlareLayer>(); go.hideFlags = HideFlags.DontSave; m_ReflectionCameras[currentCamera] = reflectionCamera; if (m_TurnOffWaterOcclusion) { reflectionCamera.useOcclusionCulling = false; } } } }
private void Awake() { m_renderer = GetComponent <Renderer>(); if (m_renderer == null) { enabled = false; } m_HardwareWaterSupport = FindHardwareWaterSupport(); // Optionally disable pixel lights for reflection/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (disablePixelLights) { QualitySettings.pixelLightCount = 0; } m_mode = GetWaterMode(); // Setup shader keywords based on water mode switch (m_mode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } }
void Awake() { RenderTextureFormat[] optionalFormats = new RenderTextureFormat[] { RenderTextureFormat.RGB565, RenderTextureFormat.ARGB1555, RenderTextureFormat.ARGB4444, RenderTextureFormat.ARGB32, RenderTextureFormat.Default }; for (int i = 0; i < optionalFormats.Length; ++i) { if (SystemInfo.SupportsRenderTextureFormat(optionalFormats[i])) { m_RenderTextureFormat = optionalFormats[i]; break; } } waterRenderer = GetComponent <MeshRenderer>(); waterMaterials = waterRenderer.sharedMaterials; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); waterTrans = this.transform; }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { if (!enabled || !renderer || !renderer.sharedMaterial || !renderer.enabled) { return; } Camera cam = Camera.current; if (!cam) { return; } // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera, refractionCamera; CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); // 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/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (m_DisablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(cam, reflectionCamera); UpdateCameraModes(cam, refractionCamera); // Render reflection if needed if (mode >= WaterMode.Reflective) { // NOTE: Added by MichaelL on Oct. 21, 2010: Unity has a bug when shadows are mixed with reflections. float saved = QualitySettings.shadowDistance; QualitySettings.shadowDistance = 0.0f; // Reflect camera around reflection plane float d = -Vector3.Dot(normal, pos) - m_ClipPlaneOffset; Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, reflectionPlane); Vector3 newpos = reflection.MultiplyPoint(cam.transform.position); 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 = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); Matrix4x4 projection = cam.projectionMatrix; CalculateObliqueMatrix(ref projection, clipPlane); reflectionCamera.projectionMatrix = projection; reflectionCamera.cullingMask = ~(1 << 4) & m_ReflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; GL.SetRevertBackfacing(true); { Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.position = newpos; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); reflectionCamera.Render(); } GL.SetRevertBackfacing(false); renderer.sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture); QualitySettings.shadowDistance = saved; } // Render refraction if (mode >= WaterMode.Refractive) { refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); Matrix4x4 projection = cam.projectionMatrix; CalculateObliqueMatrix(ref projection, clipPlane); refractionCamera.projectionMatrix = projection; refractionCamera.cullingMask = ~(1 << 4) & m_RefractLayers.value; // never render water layer refractionCamera.targetTexture = m_RefractionTexture; refractionCamera.transform.position = cam.transform.position; refractionCamera.transform.rotation = cam.transform.rotation; refractionCamera.Render(); renderer.sharedMaterial.SetTexture("_RefractionTex", m_RefractionTexture); } // Restore pixel light count if (m_DisablePixelLights) { QualitySettings.pixelLightCount = oldPixelLightCount; } // Setup shader keywords based on water mode switch (mode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { if (!enabled || !GetComponent <Renderer>() || !GetComponent <Renderer>().sharedMaterial || !GetComponent <Renderer>().enabled) { return; } Camera cam = Camera.current; if (!cam) { return; } // Render only once per camera float lastRender; if (p.camState.TryGetValue(cam, out lastRender)) { if (Mathf.Approximately(Time.time, lastRender) && Application.isPlaying) { return; } p.camState[cam] = Time.time; } else { p.camState.Add(cam, Time.time); } // Safeguard from recursive water reflections. if (recursiveGuard) { return; } recursiveGuard = true; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. p.hwSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera, refractionCamera; CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); // 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/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (p.disablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(cam, reflectionCamera); UpdateCameraModes(cam, refractionCamera); // Render reflection if needed if ((mode & WaterMode.Reflective) == WaterMode.Reflective && !IsSceneView2D()) { // Reflect camera around reflection plane float d = -Vector3.Dot(normal, pos) - p.clipPlaneOffset; Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, 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 = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); reflectionCamera.cullingMask = ~(1 << 4) & p.reflectLayers.value; // never render water layer reflectionCamera.targetTexture = p.reflTex; GL.invertCulling = true; reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); reflectionCamera.Render(); reflectionCamera.transform.position = oldpos; GL.invertCulling = false; GetComponent <Renderer>().sharedMaterial.SetTexture("_ReflectionTex", p.reflTex); } // Render refraction if ((mode & WaterMode.Refractive) == WaterMode.Refractive && !IsSceneView2D()) { refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); refractionCamera.cullingMask = ~(1 << 4) & p.refractLayers.value; // never render water layer refractionCamera.targetTexture = p.refrTex; refractionCamera.transform.position = cam.transform.position; refractionCamera.transform.rotation = cam.transform.rotation; refractionCamera.Render(); GetComponent <Renderer>().sharedMaterial.SetTexture("_RefractionTex", p.refrTex); } // Restore pixel light count if (p.disablePixelLights) { QualitySettings.pixelLightCount = oldPixelLightCount; } recursiveGuard = false; }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { if( !enabled || !renderer || !renderer.sharedMaterial || !renderer.enabled ) return; Camera cam = Camera.current; if( !cam ) return; // Safeguard from recursive water reflections. if( s_InsideWater ) return; s_InsideWater = true; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera, refractionCamera; CreateWaterObjects( cam, out reflectionCamera, out refractionCamera ); // 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/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if( m_DisablePixelLights ) QualitySettings.pixelLightCount = 0; UpdateCameraModes( cam, reflectionCamera ); UpdateCameraModes( cam, refractionCamera ); // Render reflection if needed if( mode >= WaterMode.Reflective ) { // Reflect camera around reflection plane float d = -Vector3.Dot (normal, pos) - m_ClipPlaneOffset; Vector4 reflectionPlane = new Vector4 (normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.zero; CalculateReflectionMatrix (ref reflection, 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 = CameraSpacePlane( reflectionCamera, pos, normal, 1.0f ); Matrix4x4 projection = cam.projectionMatrix; CalculateObliqueMatrix (ref projection, clipPlane); reflectionCamera.projectionMatrix = projection; reflectionCamera.cullingMask = ~(1<<4) & m_ReflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; GL.SetRevertBackfacing (true); reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); reflectionCamera.Render(); reflectionCamera.transform.position = oldpos; GL.SetRevertBackfacing (false); renderer.sharedMaterial.SetTexture( "_ReflectionTex", m_ReflectionTexture ); } // Render refraction if( mode >= WaterMode.Refractive ) { refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane( refractionCamera, pos, normal, -1.0f ); Matrix4x4 projection = cam.projectionMatrix; CalculateObliqueMatrix (ref projection, clipPlane); refractionCamera.projectionMatrix = projection; refractionCamera.cullingMask = ~(1<<4) & m_RefractLayers.value; // never render water layer refractionCamera.targetTexture = m_RefractionTexture; refractionCamera.transform.position = cam.transform.position; refractionCamera.transform.rotation = cam.transform.rotation; refractionCamera.Render(); renderer.sharedMaterial.SetTexture( "_RefractionTex", m_RefractionTexture ); } // Restore pixel light count if( m_DisablePixelLights ) QualitySettings.pixelLightCount = oldPixelLightCount; // Setup shader keywords based on water mode switch( mode ) { case WaterMode.Simple: Shader.EnableKeyword( "WATER_SIMPLE" ); Shader.DisableKeyword( "WATER_REFLECTIVE" ); Shader.DisableKeyword( "WATER_REFRACTIVE" ); break; case WaterMode.Reflective: Shader.DisableKeyword( "WATER_SIMPLE" ); Shader.EnableKeyword( "WATER_REFLECTIVE" ); Shader.DisableKeyword( "WATER_REFRACTIVE" ); break; case WaterMode.Refractive: Shader.DisableKeyword( "WATER_SIMPLE" ); Shader.DisableKeyword( "WATER_REFLECTIVE" ); Shader.EnableKeyword( "WATER_REFRACTIVE" ); break; } s_InsideWater = false; }
// On-demand create any objects we need for water void CreateWaterObjects(Camera currentCamera, out Camera reflectionCamera, out Camera refractionCamera) { WaterMode mode = GetWaterMode(); reflectionCamera = null; refractionCamera = null; if (mode >= WaterMode.Reflective) { // Reflection render texture if (!m_ReflectionTexture0 || m_OldReflectionTextureSize != textureSize) { if (m_ReflectionTexture0) { DestroyImmediate(m_ReflectionTexture0); } m_ReflectionTexture0 = new RenderTexture(textureSize, textureSize, 16); m_ReflectionTexture0.name = "__WaterReflection" + GetInstanceID(); m_ReflectionTexture0.isPowerOfTwo = true; m_ReflectionTexture0.hideFlags = HideFlags.DontSave; } if (currentCamera.stereoEnabled && (!m_ReflectionTexture1 || m_OldReflectionTextureSize != textureSize)) { if (m_ReflectionTexture1) { DestroyImmediate(m_ReflectionTexture1); } m_ReflectionTexture1 = new RenderTexture(textureSize, textureSize, 16); // m_ReflectionTexture1.name = "__WaterReflection1" + GetInstanceID(); m_ReflectionTexture1.isPowerOfTwo = true; m_ReflectionTexture1.hideFlags = HideFlags.DontSave; } m_OldReflectionTextureSize = textureSize; // Camera for reflection m_ReflectionCameras.TryGetValue(currentCamera, out reflectionCamera); if (!reflectionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO { GameObject go = new GameObject("Water Refl Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox)); reflectionCamera = go.GetComponent <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; } } if (mode >= WaterMode.Refractive) { // Refraction render texture if (!m_RefractionTexture0 || m_OldRefractionTextureSize != textureSize) { if (m_RefractionTexture0) { DestroyImmediate(m_RefractionTexture0); } m_RefractionTexture0 = new RenderTexture(textureSize, textureSize, 16); m_RefractionTexture0.name = "__WaterRefraction" + GetInstanceID(); m_RefractionTexture0.isPowerOfTwo = true; m_RefractionTexture0.hideFlags = HideFlags.DontSave; } if (currentCamera.stereoEnabled && (!m_RefractionTexture1 || m_OldRefractionTextureSize != textureSize)) { if (m_RefractionTexture1) { DestroyImmediate(m_RefractionTexture1); } m_RefractionTexture1 = new RenderTexture(textureSize, textureSize, 16); // m_RefractionTexture1.name = "__WaterReflection1" + GetInstanceID(); m_RefractionTexture1.isPowerOfTwo = true; m_RefractionTexture1.hideFlags = HideFlags.DontSave; } m_OldRefractionTextureSize = textureSize; // Camera for refraction m_RefractionCameras.TryGetValue(currentCamera, out refractionCamera); if (!refractionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO { GameObject go = new GameObject("Water Refr Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox)); refractionCamera = go.GetComponent <Camera>(); refractionCamera.enabled = false; refractionCamera.transform.position = transform.position; refractionCamera.transform.rotation = transform.rotation; refractionCamera.gameObject.AddComponent <FlareLayer>(); go.hideFlags = HideFlags.HideAndDontSave; m_RefractionCameras[currentCamera] = refractionCamera; } } }
// This just sets up some matrices in the material; for really // old cards to make water texture scroll. void Update() { if (!GetComponent <Renderer>()) { return; } Material mat = GetComponent <Renderer>().sharedMaterial; if (!mat) { return; } Vector4 waveSpeed = mat.GetVector("WaveSpeed"); float waveScale = mat.GetFloat("_WaveScale"); Vector4 waveScale4 = new Vector4(waveScale, waveScale, waveScale * 0.4f, waveScale * 0.45f); // Time since level load, and do intermediate calculations with doubles double t = Time.timeSinceLevelLoad / 20.0; Vector4 offsetClamped = new Vector4( (float)System.Math.IEEERemainder(waveSpeed.x * waveScale4.x * t, 1.0), (float)System.Math.IEEERemainder(waveSpeed.y * waveScale4.y * t, 1.0), (float)System.Math.IEEERemainder(waveSpeed.z * waveScale4.z * t, 1.0), (float)System.Math.IEEERemainder(waveSpeed.w * waveScale4.w * t, 1.0) ); mat.SetVector("_WaveOffset", offsetClamped); mat.SetVector("_WaveScale4", waveScale4); Vector3 waterSize = GetComponent <Renderer>().bounds.size; Vector3 scale = new Vector3(waterSize.x * waveScale4.x, waterSize.z * waveScale4.y, 1); Matrix4x4 scrollMatrix = Matrix4x4.TRS(new Vector3(offsetClamped.x, offsetClamped.y, 0), Quaternion.identity, scale); mat.SetMatrix("_WaveMatrix", scrollMatrix); scale = new Vector3(waterSize.x * waveScale4.z, waterSize.z * waveScale4.w, 1); scrollMatrix = Matrix4x4.TRS(new Vector3(offsetClamped.z, offsetClamped.w, 0), Quaternion.identity, scale); mat.SetMatrix("_WaveMatrix2", scrollMatrix); if (!enabled || !GetComponent <Renderer>() || !GetComponent <Renderer>().sharedMaterial || !GetComponent <Renderer>().enabled) { return; } Camera cam = Camera.main; if (!cam) { return; } // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera, refractionCamera; CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); // 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/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (m_DisablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(cam, reflectionCamera); UpdateCameraModes(cam, refractionCamera); // Render reflection if needed if (mode >= WaterMode.Reflective) { // Reflect camera around reflection plane float d = -Vector3.Dot(normal, pos) - m_ClipPlaneOffset; Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, 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 = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); reflectionCamera.cullingMask = ~(1 << 4) & m_ReflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; GL.SetRevertBackfacing(true); reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); reflectionCamera.Render(); reflectionCamera.transform.position = oldpos; GL.SetRevertBackfacing(false); GetComponent <Renderer>().sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture); } // Render refraction if (mode >= WaterMode.Refractive) { refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); refractionCamera.cullingMask = ~(1 << 4) & m_RefractLayers.value; // never render water layer refractionCamera.targetTexture = m_RefractionTexture; refractionCamera.transform.position = cam.transform.position; refractionCamera.transform.rotation = cam.transform.rotation; refractionCamera.Render(); GetComponent <Renderer>().sharedMaterial.SetTexture("_RefractionTex", m_RefractionTexture); } // Restore pixel light count if (m_DisablePixelLights) { QualitySettings.pixelLightCount = oldPixelLightCount; } // Setup shader keywords based on water mode switch (mode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; }
public void OnWillRenderObject() { if (!enabled || !GetComponent <Renderer> () || !GetComponent <Renderer> ().sharedMaterial || !GetComponent <Renderer> ().enabled) { return; } Camera cam = Camera.current; if (!cam) { return; } if (s_InsideWater) { return; } s_InsideWater = true; m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera, refractionCamera; CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); Vector3 pos = transform.position; Vector3 normal = transform.up; int oldPixelLightCount = QualitySettings.pixelLightCount; if (disablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(cam, reflectionCamera); UpdateCameraModes(cam, refractionCamera); if (mode >= WaterMode.Reflective) { float d = -Vector3.Dot(normal, pos) - clipPlaneOffset; Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, reflectionPlane); Vector3 oldpos = cam.transform.position; Vector3 newpos = reflection.MultiplyPoint(oldpos); reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection; Vector4 clipPlane = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); reflectionCamera.cullingMask = ~(1 << 4) & reflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; GL.invertCulling = true; reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); reflectionCamera.Render(); reflectionCamera.transform.position = oldpos; GL.invertCulling = false; GetComponent <Renderer> ().sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture); } if (mode >= WaterMode.Refractive) { refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); refractionCamera.cullingMask = ~(1 << 4) & refractLayers.value; refractionCamera.targetTexture = m_RefractionTexture; refractionCamera.transform.position = cam.transform.position; refractionCamera.transform.rotation = cam.transform.rotation; refractionCamera.Render(); GetComponent <Renderer> ().sharedMaterial.SetTexture("_RefractionTex", m_RefractionTexture); } if (disablePixelLights) { QualitySettings.pixelLightCount = oldPixelLightCount; } switch (mode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; }
public void OnWillRenderObject() { if (!enabled || !renderer || !renderer.sharedMaterial || !renderer.enabled) { return; } Camera current = Camera.current; if (!current) { return; } if (s_InsideWater) { return; } s_InsideWater = true; m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode waterMode = GetWaterMode(); Camera camera; Camera camera2; CreateWaterObjects(current, out camera, out camera2); Vector3 position = transform.position; Vector3 up = transform.up; Int32 pixelLightCount = QualitySettings.pixelLightCount; if (m_DisablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(current, camera); UpdateCameraModes(current, camera2); if (waterMode >= WaterMode.Reflective) { Single w = -Vector3.Dot(up, position) - m_ClipPlaneOffset; Vector4 plane = new Vector4(up.x, up.y, up.z, w); Matrix4x4 zero = Matrix4x4.zero; CalculateReflectionMatrix(ref zero, plane); Vector3 position2 = current.transform.position; Vector3 position3 = zero.MultiplyPoint(position2); camera.worldToCameraMatrix = current.worldToCameraMatrix * zero; Vector4 clipPlane = CameraSpacePlane(camera, position, up, 1f); Matrix4x4 projectionMatrix = current.projectionMatrix; CalculateObliqueMatrix(ref projectionMatrix, clipPlane); camera.projectionMatrix = projectionMatrix; camera.cullingMask = (-17 & m_ReflectLayers.value); camera.targetTexture = m_ReflectionTexture; GL.SetRevertBackfacing(true); camera.transform.position = position3; Vector3 eulerAngles = current.transform.eulerAngles; camera.transform.eulerAngles = new Vector3(-eulerAngles.x, eulerAngles.y, eulerAngles.z); camera.Render(); camera.transform.position = position2; GL.SetRevertBackfacing(false); renderer.sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture); } if (waterMode >= WaterMode.Refractive) { camera2.worldToCameraMatrix = current.worldToCameraMatrix; Vector4 clipPlane2 = CameraSpacePlane(camera2, position, up, -1f); Matrix4x4 projectionMatrix2 = current.projectionMatrix; CalculateObliqueMatrix(ref projectionMatrix2, clipPlane2); camera2.projectionMatrix = projectionMatrix2; camera2.cullingMask = (-17 & m_RefractLayers.value); camera2.targetTexture = m_RefractionTexture; camera2.transform.position = current.transform.position; camera2.transform.rotation = current.transform.rotation; camera2.Render(); renderer.sharedMaterial.SetTexture("_RefractionTex", m_RefractionTexture); } if (m_DisablePixelLights) { QualitySettings.pixelLightCount = pixelLightCount; } switch (waterMode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { if (!enabled || !GetComponent <Renderer>() || !GetComponent <Renderer>().sharedMaterial || !GetComponent <Renderer>().enabled) { return; } Camera cam = Camera.current; if (!cam) { return; } // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera, refractionCamera; CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); // 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/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (disablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(cam, reflectionCamera); UpdateCameraModes(cam, refractionCamera); // Render reflection if needed if (mode >= WaterMode.Reflective) { // 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 = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, 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 = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); reflectionCamera.cullingMask = ~(1 << 4) & reflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture;
public void OnWillRenderObject() { if (!base.enabled || !GetComponent <Renderer>() || !GetComponent <Renderer>().sharedMaterial || !GetComponent <Renderer>().enabled) { return; } Camera current = Camera.current; if ((bool)current && !s_InsideWater) { s_InsideWater = true; m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode waterMode = GetWaterMode(); CreateWaterObjects(current, out Camera reflectionCamera, out Camera refractionCamera); Vector3 position = base.transform.position; Vector3 up = base.transform.up; int pixelLightCount = QualitySettings.pixelLightCount; if (m_DisablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(current, reflectionCamera); UpdateCameraModes(current, refractionCamera); if (waterMode >= WaterMode.Reflective) { float w = 0f - Vector3.Dot(up, position) - m_ClipPlaneOffset; Vector4 plane = new Vector4(up.x, up.y, up.z, w); Matrix4x4 reflectionMat = Matrix4x4.zero; CalculateReflectionMatrix(ref reflectionMat, plane); Vector3 position2 = current.transform.position; Vector3 position3 = reflectionMat.MultiplyPoint(position2); reflectionCamera.worldToCameraMatrix = current.worldToCameraMatrix * reflectionMat; Vector4 clipPlane = CameraSpacePlane(reflectionCamera, position, up, 1f); Matrix4x4 projection = current.projectionMatrix; CalculateObliqueMatrix(ref projection, clipPlane); reflectionCamera.projectionMatrix = projection; reflectionCamera.cullingMask = (-17 & m_ReflectLayers.value); reflectionCamera.targetTexture = m_ReflectionTexture; GL.SetRevertBackfacing(revertBackFaces: true); reflectionCamera.transform.position = position3; Vector3 eulerAngles = current.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(0f - eulerAngles.x, eulerAngles.y, eulerAngles.z); reflectionCamera.Render(); reflectionCamera.transform.position = position2; GL.SetRevertBackfacing(revertBackFaces: false); GetComponent <Renderer>().sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture); } if (waterMode >= WaterMode.Refractive) { refractionCamera.worldToCameraMatrix = current.worldToCameraMatrix; Vector4 clipPlane2 = CameraSpacePlane(refractionCamera, position, up, -1f); Matrix4x4 projection2 = current.projectionMatrix; CalculateObliqueMatrix(ref projection2, clipPlane2); refractionCamera.projectionMatrix = projection2; refractionCamera.cullingMask = (-17 & m_RefractLayers.value); refractionCamera.targetTexture = m_RefractionTexture; refractionCamera.transform.position = current.transform.position; refractionCamera.transform.rotation = current.transform.rotation; refractionCamera.Render(); GetComponent <Renderer>().sharedMaterial.SetTexture("_RefractionTex", m_RefractionTexture); } if (m_DisablePixelLights) { QualitySettings.pixelLightCount = pixelLightCount; } switch (waterMode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; } }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { if (!enabled || !GetComponent <Renderer>() || !GetComponent <Renderer>().sharedMaterial || !GetComponent <Renderer>().enabled) { return; } if (!m_Terrain) { GameObject go = GameObject.Find("Terrain"); if (!go) { return; } m_Terrain = go.GetComponent(typeof(Terrain)) as Terrain; if (!m_Terrain) { return; } } Camera cam = Camera.current; if (!cam) { return; } // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Shader newShader = (mode == WaterMode.Refractive) ? m_ShaderFull : m_ShaderSimple; if (GetComponent <Renderer>().sharedMaterial.shader != newShader) { GetComponent <Renderer>().sharedMaterial.shader = newShader; } Camera reflectionCamera, refractionCamera; CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); // 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/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (m_DisablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(cam, reflectionCamera); UpdateCameraModes(cam, refractionCamera); bool oldSoftVegetation = QualitySettings.softVegetation; QualitySettings.softVegetation = false; // Render reflection if needed if (mode >= WaterMode.Reflective) { // Reflect camera around reflection plane float d = -Vector3.Dot(normal, pos) - m_ClipPlaneOffset; Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, 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 = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); Matrix4x4 projection = cam.projectionMatrix; CalculateObliqueMatrix(ref projection, clipPlane); reflectionCamera.projectionMatrix = projection; reflectionCamera.cullingMask = ~(1 << 4) & m_ReflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; GL.SetRevertBackfacing(true); reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(0, euler.y, euler.z); // don't render tree meshes or grass in reflection :) float oldDetailDist = m_Terrain.detailObjectDistance; float oldTreeDist = m_Terrain.treeDistance; float oldTreeBillDist = m_Terrain.treeBillboardDistance; float oldSplatDist = m_Terrain.basemapDistance; m_Terrain.detailObjectDistance = 0.0f; m_Terrain.treeBillboardDistance = 0.0f; m_Terrain.basemapDistance = 0.0f; reflectionCamera.Render(); m_Terrain.detailObjectDistance = oldDetailDist; m_Terrain.treeDistance = oldTreeDist; m_Terrain.treeBillboardDistance = oldTreeBillDist; m_Terrain.basemapDistance = oldSplatDist; reflectionCamera.transform.position = oldpos; GL.SetRevertBackfacing(false); GetComponent <Renderer>().sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture); } // Render refraction if (mode >= WaterMode.Refractive) { refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); Matrix4x4 projection = cam.projectionMatrix; CalculateObliqueMatrix(ref projection, clipPlane); refractionCamera.projectionMatrix = projection; refractionCamera.cullingMask = ~(1 << 4) & m_RefractLayers.value; // never render water layer refractionCamera.targetTexture = m_RefractionTexture; refractionCamera.transform.position = cam.transform.position; refractionCamera.transform.rotation = cam.transform.rotation; // don't render trees or grass in refraction :) float oldDetailDist = m_Terrain.detailObjectDistance; float oldTreeDist = m_Terrain.treeDistance; float oldTreeBillDist = m_Terrain.treeBillboardDistance; m_Terrain.detailObjectDistance = 0.0f; m_Terrain.treeDistance = 0.0f; m_Terrain.treeBillboardDistance = 0.0f; refractionCamera.Render(); m_Terrain.detailObjectDistance = oldDetailDist; m_Terrain.treeDistance = oldTreeDist; m_Terrain.treeBillboardDistance = oldTreeBillDist; GetComponent <Renderer>().sharedMaterial.SetTexture("_RefractionTex", m_RefractionTexture); } QualitySettings.softVegetation = oldSoftVegetation; // Restore pixel light count if (m_DisablePixelLights) { QualitySettings.pixelLightCount = oldPixelLightCount; } // Setup shader keywords based on water mode switch (mode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; }
//----------------------------------------------------- void Start() { // -- Initialisation variables membres -- mLoopWaterMode = false; mWaterMode = WaterMode.turbulent; mWater = null; mWaterRefract = null; // -- Variables Animation -- mEmptyAnim = false; mEmptyAnimProg = 0f; mEmptyAnimStart = 0f; mEmptyAnimEnd = 0f; mEmptyAnimRefStart = 0f; mEmptyAnimRefEnd = 0f; mCalmAnim = false; mCalmAnimProg = 0f; mCalmAnimBlendStart = 0f; mCalmAnimBlendEnd = 0f; mCalmAnimGlobAlphaStart = 0f; mCalmAnimGlobAlphaEnd = 0f; mCalmAnimMinAlphaStart = 0f; mCalmAnimMinAlphaEnd = 0f; mCalmAnimMinCoefStart = 0f; mCalmAnimMinCoefEnd = 0f; mCalmAnimAmountStart = 0f; mCalmAnimAmountEnd = 0f; mCalmAnimBmpAmtStart = 0f; mCalmAnimBmpAmtEnd = 0f; // -- Récupérations des objets de la scène dont on a besoin -- mSpa = transform; Transform child, child2; for(int i=0; i<mSpa.GetChildCount(); i++) { child = mSpa.GetChild(i); if(child.name == sWaterParentName) { for(int j=0; j<child.GetChildCount(); j++) { child2 = child.GetChild(j); if(child2.name.Equals(sWaterSpecName)) mWater = child2.gameObject; // Eau (celle avec le shader DispNormRimSpec-like) else if(child2.name.Equals(sWaterRefractName)) mWaterRefract = child2.gameObject; // Eau (avec réfraction) } } } // foreach child // -- Si un objet est absent, afficher une erreur et désactiver le script -- if(mWater == null) { DeactivateWithLogError(sWaterSpecName); return; } if(mWaterRefract == null) { DeactivateWithLogError(sWaterRefractName); return; } // mWaterMeshDefaultFilledY = mWater.transform.localPosition.y; // mWaterRefMeshDefaultFilledY = mWaterRefract.transform.localPosition.y; mWaterMeshFilledY = mWater.transform.localPosition.y; mWaterRefMeshFilledY = mWaterRefract.transform.localPosition.y; mWaterMeshEmptyY = mWaterMeshFilledY-mDecalageEauVide; if(usefullData.lowTechnologie) { Shader shad =Shader.Find("Transparent/Diffuse"); mWater.GetComponent<Renderer>().material.shader = shad; mWater.GetComponent<Renderer>().material.SetColor("_Color", new Color (1.0f,1.0f,1.0f,0.5f)); mWaterRefract.GetComponent<Renderer>().enabled=false; //mWaterRefract.renderer.material.shader = shad; //mWaterRefract.renderer.material.SetColor("_Color", new Color (1.0f,1.0f,1.0f,0.5f)); } }
//----------------------------------------------------- void LoopWaterMode() { if(mEmptyAnim) return; mWaterMode = (WaterMode) (((int)mWaterMode+1) % (Enum.GetNames(typeof(WaterMode)).Length)); if(mWaterMode == WaterMode.empty || mWaterMode == WaterMode.turbulent) { mEmptyAnim = true; mEmptyAnimProg = 0f; mEmptyAnimStart = (mWaterMode == WaterMode.empty) ? mWaterMeshFilledY : mWaterMeshEmptyY; mEmptyAnimEnd = (mWaterMode == WaterMode.empty) ? mWaterMeshEmptyY : mWaterMeshFilledY; mEmptyAnimRefStart = (mWaterMode == WaterMode.empty) ? mWaterRefMeshFilledY : mWaterMeshEmptyY; mEmptyAnimRefEnd = (mWaterMode == WaterMode.empty) ? mWaterMeshEmptyY : mWaterRefMeshFilledY; if(mWaterMode == WaterMode.empty) // Lancer l'extinction du spot principal si vidange { if(mSpa.GetComponent<Function_SpaConfigLight>()!=null) mSpa.GetComponent<Function_SpaConfigLight>().DecreaseMainSpotlight(); } } if(mWaterMode != WaterMode.empty) SetWaterMode(mWaterMode == WaterMode.calm); }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { if (!enabled || !GetComponent <Renderer>() || !GetComponent <Renderer>().sharedMaterial || !GetComponent <Renderer>().enabled) { return; } Camera cam = Camera.current; if (!cam) { return; } // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; var act = gameObject.activeInHierarchy && enabled; if (!act) { Cleanup(); return; } // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera, refractionCamera; CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); // 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/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (disablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(cam, reflectionCamera); //UpdateCameraModes(cam, refractionCamera); // Render reflection if needed if (mode >= WaterMode.Reflective) { // 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 = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, 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 = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); // Set custom culling matrix from the current camera reflectionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix; reflectionCamera.cullingMask = ~(1 << 4) & reflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; bool oldCulling = GL.invertCulling; GL.invertCulling = !oldCulling; reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); reflectionCamera.Render(); reflectionCamera.transform.position = oldpos; GL.invertCulling = oldCulling; GetComponent <Renderer>().sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture); if (isRefract) { Cleanup(); isRefract = false; } } if (mode >= WaterMode.Refractive) { isRefract = true; CommandBuffer buf = null; // Did we already add the command buffer on this camera? Nothing to do then. if (m_Cameras.ContainsKey(cam)) { return; } buf = new CommandBuffer(); buf.name = "Grab Refraction"; m_Cameras[cam] = buf; // copy screen into temporary RT int screenCopyID = Shader.PropertyToID("_ScreenCopyTexture"); buf.GetTemporaryRT(screenCopyID, textureSize, textureSize, 0, FilterMode.Bilinear); buf.Blit(builtinRenderTextureType, screenCopyID); buf.SetGlobalTexture("_RefractionTex", screenCopyID); buf.ReleaseTemporaryRT(screenCopyID); cam.AddCommandBuffer(cameraEvent, buf); } // Restore pixel light count if (disablePixelLights) { QualitySettings.pixelLightCount = oldPixelLightCount; } // Setup shader keywords based on water mode switch (mode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; }
private void CreateWaterObjects(Camera currentCamera, out Camera reflectionCamera, out Camera refractionCamera) { WaterMode waterMode = GetWaterMode(); reflectionCamera = null; refractionCamera = null; if (waterMode >= WaterMode.Reflective) { if (!m_ReflectionTexture || m_OldReflectionTextureSize != m_TextureSize) { if (m_ReflectionTexture) { DestroyImmediate(m_ReflectionTexture); } m_ReflectionTexture = new RenderTexture(m_TextureSize, m_TextureSize, 16); m_ReflectionTexture.name = "__WaterReflection" + GetInstanceID(); m_ReflectionTexture.isPowerOfTwo = true; m_ReflectionTexture.hideFlags = HideFlags.DontSave; m_OldReflectionTextureSize = m_TextureSize; } m_ReflectionCameras.TryGetValue(currentCamera, out reflectionCamera); if (!reflectionCamera) { GameObject gameObject = new GameObject(String.Concat(new Object[] { "Water Refl Camera id", GetInstanceID(), " for ", currentCamera.GetInstanceID() }), new Type[] { typeof(Camera), typeof(Skybox) }); reflectionCamera = gameObject.camera; reflectionCamera.enabled = false; reflectionCamera.transform.position = transform.position; reflectionCamera.transform.rotation = transform.rotation; reflectionCamera.gameObject.AddComponent("FlareLayer"); gameObject.hideFlags = HideFlags.HideAndDontSave; m_ReflectionCameras[currentCamera] = reflectionCamera; } } if (waterMode >= WaterMode.Refractive) { if (!m_RefractionTexture || m_OldRefractionTextureSize != m_TextureSize) { if (m_RefractionTexture) { DestroyImmediate(m_RefractionTexture); } m_RefractionTexture = new RenderTexture(m_TextureSize, m_TextureSize, 16); m_RefractionTexture.name = "__WaterRefraction" + GetInstanceID(); m_RefractionTexture.isPowerOfTwo = true; m_RefractionTexture.hideFlags = HideFlags.DontSave; m_OldRefractionTextureSize = m_TextureSize; } m_RefractionCameras.TryGetValue(currentCamera, out refractionCamera); if (!refractionCamera) { GameObject gameObject2 = new GameObject(String.Concat(new Object[] { "Water Refr Camera id", GetInstanceID(), " for ", currentCamera.GetInstanceID() }), new Type[] { typeof(Camera), typeof(Skybox) }); refractionCamera = gameObject2.camera; refractionCamera.enabled = false; refractionCamera.transform.position = transform.position; refractionCamera.transform.rotation = transform.rotation; refractionCamera.gameObject.AddComponent("FlareLayer"); gameObject2.hideFlags = HideFlags.HideAndDontSave; m_RefractionCameras[currentCamera] = refractionCamera; } } }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { if (!enabled || !renderer || !renderer.sharedMaterial || !renderer.enabled) { return; } Camera cam = Camera.current; if (!cam || !cam.CompareTag("MainCamera")) { return; } // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera; //, refractionCamera; CreateWaterObjects(cam, out reflectionCamera); //, out refractionCamera ); // find out the reflection plane: position and normal in world space Vector3 pos = transform.position; Vector3 normal = transform.up; //avoid frustum error ugh //avoid frustum error ugh //bool frustumError = false; //int zeroVectors = 0; //var camRotation = cam.transform.rotation; //if ( camRotation.x == 0 ) // zeroVectors++; //if ( camRotation.y == 0 ) // zeroVectors++; //if ( camRotation.z == 0 ) // zeroVectors++; //if ( zeroVectors > 1 ) //{ // frustumError = true; //} // Optionally disable pixel lights for reflection/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (m_DisablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(cam, reflectionCamera); //UpdateCameraModes( cam, refractionCamera ); // Render reflection if needed if (mode >= WaterMode.Reflective) // && !frustumError ) { // Reflect camera around reflection plane float d = -Vector3.Dot(normal, pos) - m_ClipPlaneOffset; Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, reflectionPlane); Vector3 oldpos = cam.transform.position; //Debug.Log( $"oldpos: {oldpos}" ); Vector3 newpos = reflection.MultiplyPoint(oldpos); //Debug.Log( $"newpos: {newpos}" ); reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection; // Setup oblique projection matrix so that near plane is our reflection // reflectionCamera.worldToCameraMatrix = new Matrix4x4( // //-0.53887f, 0.17386f, 0.82425f, 1.63841f, // //0.71059f, -0.43168f, 0.55562f, -10.83935f, // //0.45242f, 0.88511f, 0.10907f, 21.07603f, // //0.00000f 0.00000f 0.00000f 1.00000f, // new Vector4( -0.53887f, // 0.71059f, // 0.45242f, // 0.00000f ), // new Vector4( 0.17386f, // -0.43168f, // 0.88511f, // 0.00000f ), // new Vector4( 0.82425f, // 0.55562f, // 0.10907f, // 0.00000f ), //new Vector4( 1.63841f, // -10.83935f, // 21.07603f, // 1.00000f ) ); // plane. This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); //clipPlane = new Vector4( 0.0f, -1.0f, -0.3f, -15.5f ); //Debug.Log( $"clipPlane: {clipPlane}" ); reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); Debug.Log($"reflectionCamera.projectionMatrix: {reflectionCamera.projectionMatrix}"); //Matrix4x4 m = cam.CalculateObliqueMatrix( clipPlane ); //reflectionCamera.projectionMatrix = m; //Debug.Log( $"cam.CalculateObliqueMatrix( clipPlane ): {cam.CalculateObliqueMatrix( clipPlane )}" ); //reflectionCamera.projectionMatrix = new Matrix4x4( //new Vector4( 0.63938f, 0.00000f, 0.00000f, 0.00000f ), //new Vector4( 0.00000f, 1.73205f, 0.00000f, 0.00000f ), //new Vector4( -0.03392f, - 2.21662f, 0.33250f, -35.86786f ), //new Vector4( 0.00000f, 0.00000f, - 1.00000f, 0.00000f ) ); //new Vector4( 0.6393847f, // 0.00000f, // -0.3562191f, // 0.00000f ), //new Vector4( 0.00000f, // 1.732051f, // 1.846399f, // 0.00000f ), //new Vector4( 0.00000f, // 0.00000f, // -2.62263f, // -1.00000f ), //new Vector4( 0.00000f, // 0.00000f, // 58.63717f, // 0.00000f ) ); //0.56257 0.00000 0.00000 0.00000 //0.00000 1.00000 0.00000 0.00000 //- 0.60771 3.14996 - 5.18022 100.03530 //0.00000 0.00000 - 1.00000 0.00000 //Debug.Log( $"reflectionCamera.projectionMatrix 1 z: {reflectionCamera.projectionMatrix.GetColumn(1).z}" ); //Debug.Log( $"reflectionCamera.projectionMatrix y : {reflectionCamera.projectionMatrix.GetColumn( 2 ).z}" ); //Debug.Log( $"reflectionCamera.projectionMatrix z: {reflectionCamera.projectionMatrix.GetColumn( 3 ).z}" ); //Debug.Log( $"reflectionCamera.projectionMatrix w: {reflectionCamera.projectionMatrix.GetColumn( 3 ).w}" ); // 0.56257 0.00000 0.00000 0.00000 // 0.00000 1.00000 0.00000 0.00000 // -0.60771 3.14996 -5.18022 100.03530 // 0.00000 0.00000 -1.00000 0.00000 //new Vector4( 0.00000f, 1.73205f, 0.00000f, 0.00000f ), //new Vector4( -0.03392f, -2.21662f, 0.33250f, -35.86786f ), //new Vector4( 0.00000f, 0.00000f, -1.00000f, 0.00000f ) ); //reflectionCamera.cullingMask = ~( 1 << 4 ) & m_ReflectLayers.value; // never render water layer //reflectionCamera.targetTexture = m_ReflectionTexture; //GL.SetRevertBackfacing(true); //GL.invertCulling = true; //reflectionCamera.transform.position = newpos; //reflectionCamera.transform.position = new Vector3( 92.3f, -24.1f, 47.0f); //Vector3 euler = cam.transform.eulerAngles; //reflectionCamera.transform.eulerAngles = new Vector3( -euler.x, euler.y, euler.z ); //Debug.Log( $"reflectionCamera.projectionMatrix: {reflectionCamera.projectionMatrix}" ); //Debug.Log( $"reflectionCamera.worldToCameraMatrix: {reflectionCamera.worldToCameraMatrix}" ); //x,y: 298, 237 reflectionCamera.Render(); //reflectionCamera.transform.position = oldpos; //GL.SetRevertBackfacing(false); //GL.invertCulling = false; //renderer.sharedMaterial.SetTexture( "_ReflectionTex", m_ReflectionTexture ); } // Render refraction //if ( mode >= WaterMode.Refractive )// && !frustumError ) //{ // refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; // // Setup oblique projection matrix so that near plane is our reflection // // plane. This way we clip everything below/above it for free. // Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); // refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix( clipPlane ); // refractionCamera.cullingMask = ~( 1 << 4 ) & m_RefractLayers.value; // never render water layer // refractionCamera.targetTexture = m_RefractionTexture; // refractionCamera.transform.position = cam.transform.position; // refractionCamera.transform.rotation = cam.transform.rotation; // refractionCamera.Render(); // renderer.sharedMaterial.SetTexture( "_RefractionTex", m_RefractionTexture ); //} // Restore pixel light count if (m_DisablePixelLights) { QualitySettings.pixelLightCount = oldPixelLightCount; } // Setup shader keywords based on water mode switch (mode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; }
void CreateWaterObjects(Camera currentCamera, out Camera reflectionCamera, out Camera refractionCamera) { WaterMode mode = GetWaterMode(); reflectionCamera = null; refractionCamera = null; if (mode >= WaterMode.Reflective) { if (!m_ReflectionTexture || m_OldReflectionTextureSize != textureSize) { if (m_ReflectionTexture) { DestroyImmediate(m_ReflectionTexture); } m_ReflectionTexture = new RenderTexture(textureSize, textureSize, 16); m_ReflectionTexture.name = "__WaterReflection" + GetInstanceID(); m_ReflectionTexture.isPowerOfTwo = true; m_ReflectionTexture.hideFlags = HideFlags.DontSave; m_OldReflectionTextureSize = textureSize; } m_ReflectionCameras.TryGetValue(currentCamera, out reflectionCamera); if (!reflectionCamera) { GameObject go = new GameObject("Water Refl Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox)); reflectionCamera = go.GetComponent <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; } } if (mode >= WaterMode.Refractive) { if (!m_RefractionTexture || m_OldRefractionTextureSize != textureSize) { if (m_RefractionTexture) { DestroyImmediate(m_RefractionTexture); } m_RefractionTexture = new RenderTexture(textureSize, textureSize, 16); m_RefractionTexture.name = "__WaterRefraction" + GetInstanceID(); m_RefractionTexture.isPowerOfTwo = true; m_RefractionTexture.hideFlags = HideFlags.DontSave; m_OldRefractionTextureSize = textureSize; } m_RefractionCameras.TryGetValue(currentCamera, out refractionCamera); if (!refractionCamera) { GameObject go = new GameObject("Water Refr Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox)); refractionCamera = go.GetComponent <Camera> (); refractionCamera.enabled = false; refractionCamera.transform.position = transform.position; refractionCamera.transform.rotation = transform.rotation; refractionCamera.gameObject.AddComponent <FlareLayer> (); go.hideFlags = HideFlags.HideAndDontSave; m_RefractionCameras[currentCamera] = refractionCamera; } } }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { if (!enabled || !GetComponent<Renderer>() || !GetComponent<Renderer>().sharedMaterial || !GetComponent<Renderer>().enabled) { return; } Camera cam = Camera.current; if (!cam) { return; } // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera, refractionCamera; CreateWaterObjects(cam, AKSJF/AKLFNAILEHFNASKLBGDLFKVMSADLJGKBGKVN ,BASDKVJASKDUVHSdV ASDSDVKHABDVKSDKVBDFL // 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 = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, 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 = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); // Set custom culling matrix from the current camera reflectionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix; reflectionCamera.cullingMask = ~(1 << 4) & reflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; bool oldCulling = GL.invertCulling; GL.invertCulling = !oldCulling; reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); reflectionCamera.Render(); reflectionCamera.transform.position = oldpos; GL.invertCulling = oldCulling; GetComponent<Renderer>().sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture); }
// On-demand create any objects we need for water void CreateWaterObjects(Camera currentCamera, out Camera reflectionCamera, out Camera refractionCamera) { Debug.Log("CreateWaterObjects " + Time.realtimeSinceStartup); WaterMode mode = GetWaterMode(); reflectionCamera = null; refractionCamera = null; if (mode >= WaterMode.Reflective) { // Reflection render texture if (!m_ReflectionTexture || m_OldReflectionTextureSize != textureSize) { if (m_ReflectionTexture) { DestroyImmediate(m_ReflectionTexture); } m_ReflectionTexture = new RenderTexture(textureSize, textureSize, 16); m_ReflectionTexture.name = "__WaterReflection" + GetInstanceID(); m_ReflectionTexture.isPowerOfTwo = true; m_ReflectionTexture.hideFlags = HideFlags.DontSave; m_OldReflectionTextureSize = textureSize; } // Camera for reflection m_ReflectionCameras.TryGetValue(currentCamera, out reflectionCamera); if (!reflectionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO { // 创建一个带Camera和Skybox的GameObject GameObject go = new GameObject("Water Refl Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox)); reflectionCamera = go.GetComponent <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; Debug.Log("m_ReflectionCameras.Count = " + m_ReflectionCameras.Count + " " + go.GetInstanceID() + " " + currentCamera.GetInstanceID() + " " + currentCamera.tag + " " + GetInstanceID() + " " + Time.realtimeSinceStartup); } } if (mode >= WaterMode.Refractive) { // Refraction render texture if (!m_RefractionTexture || m_OldRefractionTextureSize != textureSize) { if (m_RefractionTexture) { DestroyImmediate(m_RefractionTexture); } m_RefractionTexture = new RenderTexture(textureSize, textureSize, 16); m_RefractionTexture.name = "__WaterRefraction" + GetInstanceID(); m_RefractionTexture.isPowerOfTwo = true; m_RefractionTexture.hideFlags = HideFlags.DontSave; m_OldRefractionTextureSize = textureSize; } // Camera for refraction m_RefractionCameras.TryGetValue(currentCamera, out refractionCamera); if (!refractionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO { GameObject go = new GameObject("Water Refr Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox)); refractionCamera = go.GetComponent <Camera>(); refractionCamera.enabled = false; refractionCamera.transform.position = transform.position; refractionCamera.transform.rotation = transform.rotation; refractionCamera.gameObject.AddComponent <FlareLayer>(); go.hideFlags = HideFlags.HideAndDontSave; m_RefractionCameras[currentCamera] = refractionCamera; Debug.Log("m_RefractionCameras.Count = " + m_RefractionCameras.Count + " " + go.GetInstanceID() + " " + currentCamera.GetInstanceID() + " " + currentCamera.tag + " " + GetInstanceID() + " " + Time.realtimeSinceStartup); } } }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { if (!enabled || !waterRenderer.enabled || waterMaterials.Length <= 0) { return; } Camera cam = Camera.current; if (!cam) { return; } camTrans = cam.transform; // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; WaterMode mode = GetWaterMode(); Camera reflectionCamera = null, refractionCamera = null; CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); if (reflectionCamera != null) { reflectionCamTrans = reflectionCamera.transform; } if (refractionCamera != null) { refractionCamTrans = refractionCamera.transform; } // find out the reflection plane: position and normal in world space Vector3 pos = waterTrans.position; Vector3 normal = waterTrans.up; // Optionally disable pixel lights for reflection/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (m_DisablePixelLights) { QualitySettings.pixelLightCount = 0; } // Render reflection if needed if (mode >= WaterMode.Reflective) { // Reflect camera around reflection plane float d = -Vector3.Dot(normal, pos) - m_ClipPlaneOffset; Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, reflectionPlane); Vector3 oldpos = camTrans.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 = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); reflectionCamera.cullingMask = ~(1 << 4) & m_ReflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; GL.SetRevertBackfacing(true); reflectionCamTrans.position = newpos; Vector3 euler = camTrans.eulerAngles; reflectionCamTrans.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); reflectionCamera.Render(); reflectionCamTrans.position = oldpos; GL.SetRevertBackfacing(false); if (waterMaterials != null) { if (waterMaterials[0] != null) { waterMaterials[0].SetTexture("_ReflectionTex", m_ReflectionTexture); } if (waterMaterials.Length > 1 && waterMaterials[1] != null) { waterMaterials[1].SetTexture("_ReflectionTex", m_ReflectionTexture); } } } // Render refraction if (mode >= WaterMode.Refractive) { refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); refractionCamera.cullingMask = ~(1 << 4) & m_RefractLayers.value; // never render water layer refractionCamera.targetTexture = m_RefractionTexture; refractionCamTrans.position = camTrans.position; refractionCamTrans.rotation = camTrans.rotation; refractionCamera.Render(); if (waterMaterials != null) { if (waterMaterials[0] != null) { waterMaterials[0].SetTexture("_RefractionTex", m_RefractionTexture); } if (waterMaterials.Length > 1 && waterMaterials[1] != null) { waterMaterials[1].SetTexture("_RefractionTex", m_RefractionTexture); } } } // Restore pixel light count if (m_DisablePixelLights) { QualitySettings.pixelLightCount = oldPixelLightCount; } // Setup shader keywords based on water mode switch (mode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_CUBE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Cube: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_CUBE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_CUBE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_CUBE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; }
private void Awake() { m_material = GetComponent<Renderer>().sharedMaterial; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport (); //m_waterMode = GetWaterMode (); m_waveSpeed = m_material.GetVector ("WaveSpeed"); m_waveScale = m_material.GetFloat ("_WaveScale"); m_waveScale4 = new Vector4 (m_waveScale, m_waveScale, m_waveScale * 0.4f, m_waveScale * 0.45f); m_material.SetVector ("_WaveScale4", m_waveScale4); m_xWaveSpeedScaled = m_waveSpeed.x * m_waveScale4.x; m_yWaveSpeedScaled = m_waveSpeed.y * m_waveScale4.y; m_zWaveSpeedScaled = m_waveSpeed.z * m_waveScale4.z; m_wWaveSpeedScaled = m_waveSpeed.w * m_waveScale4.w; m_camera = Camera.current; // CreateWaterObjects (m_camera, out m_reflectionCamera, out m_refractionCamera); // UpdateCameraModes (m_camera, m_reflectionCamera); // UpdateCameraModes (m_camera, m_refractionCamera); }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { Debug.Log("OnWillRenderObject " + Time.realtimeSinceStartup); if (!enabled || !GetComponent <Renderer>() || !GetComponent <Renderer>().sharedMaterial || !GetComponent <Renderer>().enabled) { return; } // 这里为什么不是Camera.main而是Camera.current? // 因为Camera.main相当于我们的眼睛 // 后面的camera是在处理反射相机和折射相机 // 相当于眼睛长在水面上 Camera cam = Camera.current; //Camera cam = Camera.main; if (!cam) { return; } // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); // 根据当前相机创建反射相机,纹理和折射相机,纹理 // 相机: 带skybox组件和FlareLayer // 纹理:深度缓冲16bit Camera reflectionCamera, refractionCamera; CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); // 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/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (disablePixelLights) { QualitySettings.pixelLightCount = 0; } // 把当前相机的参数给反射相机和折射相机 UpdateCameraModes(cam, reflectionCamera); UpdateCameraModes(cam, refractionCamera); // Render reflection if needed if (mode >= WaterMode.Reflective) { // Reflect camera around reflection plane // 获得反射纹理的几个流程 // 1.反射摄像机的反射矩阵 // 2.反射摄像机的投影矩阵 // 3.反射摄像机x旋转下 // 4.渲染到纹理 // 通过构建发射平面进而构建反射矩阵,并将反射矩阵设置成反射摄像机的worldToCameraMatrix // 反射平面: 所在GameObject的法线(向上)和点(就选所在GameObject的位置) float d = -Vector3.Dot(normal, pos) - clipPlaneOffset; Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, 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. // 投影矩阵 // 参考http://www.cnblogs.com/wantnon/p/4569096.html // 也就是说,oblique投影矩阵与普通投影矩阵(透视投影矩阵和正交投影矩阵)的差别是:普通投影矩阵所描述的视截体近平面与锥轴垂直, // 而oblique投影矩阵所描述的视截体近平面是斜的(与锥轴不垂直)。 // 由于水面是反射面,所以渲染反射图象时必须以视截体被水面所截的截面作为视口,即“斜视口”, // 所以必须将反射相机转化成oblique投影模式。 // reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane)就是干这个事儿。 Vector4 clipPlane = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); reflectionCamera.cullingMask = ~(1 << 4) & reflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; bool oldCulling = GL.invertCulling; GL.invertCulling = !oldCulling; reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; //反射是镜像,x转一下 reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); Debug.Log("Pre reflection.Camera.Render() Camera.current = " + Camera.current.gameObject.GetInstanceID() + " main " + Camera.main.gameObject.GetInstanceID() + " " + Time.realtimeSinceStartup); reflectionCamera.Render(); Debug.Log("Post reflection.Camera.Render() Camera.current = " + Camera.current.gameObject.GetInstanceID() + " main " + Camera.main.gameObject.GetInstanceID() + " " + Time.realtimeSinceStartup); reflectionCamera.transform.position = oldpos; GL.invertCulling = oldCulling; GetComponent <Renderer>().sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture); } // Render refraction if (mode >= WaterMode.Refractive) { refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); refractionCamera.cullingMask = ~(1 << 4) & refractLayers.value; // never render water layer refractionCamera.targetTexture = m_RefractionTexture; refractionCamera.transform.position = cam.transform.position; refractionCamera.transform.rotation = cam.transform.rotation; Debug.Log("Pre refractionCamera.Render() Camera.current = " + Camera.current.gameObject.GetInstanceID() + " main " + Camera.main.gameObject.GetInstanceID() + " " + Time.realtimeSinceStartup); refractionCamera.Render(); Debug.Log("Post refractionCamera.Render() Camera.current = " + Camera.current.gameObject.GetInstanceID() + " main " + Camera.main.gameObject.GetInstanceID() + " " + Time.realtimeSinceStartup); GetComponent <Renderer>().sharedMaterial.SetTexture("_RefractionTex", m_RefractionTexture); } // Restore pixel light count if (disablePixelLights) { QualitySettings.pixelLightCount = oldPixelLightCount; } // Setup shader keywords based on water mode switch (mode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { if(!enabled) return; if(!renderer.sharedMaterial) return; Camera cam = Camera.current; if( !cam ) return; // Safeguard from recursive water reflections. if( s_InsideWater ) return; s_InsideWater = true; bool underWater = false; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera; CreateWaterObjects(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/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if( m_DisablePixelLights ) QualitySettings.pixelLightCount = 0; UpdateCameraModes(cam, reflectionCamera); // Render reflection if needed if(mode >= WaterMode.FastAndNoRefraction) { // this should actually be accompanied along with a // special image effect, blurring out the scene etc. if(IsUnderwater(cam)) { /* reflectionCamera.depthTextureMode = DepthTextureMode.None; reflectionCamera.renderingPath = RenderingPath.Forward; reflectionCamera.transform.position = cam.transform.position; reflectionCamera.transform.rotation = cam.transform.rotation; reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; reflectionCamera.targetTexture = m_ReflectionTexture; reflectionCamera.cullingMask = ~(1<<4) & m_ReflectLayers.value; // never render water layer reflectionCamera.projectionMatrix = cam.projectionMatrix; reflectionCamera.Render(); */ if(Camera.main == cam && !cam.gameObject.GetComponent(typeof(Water3UnderwaterEffect)) ) { cam.gameObject.AddComponent(typeof(Water3UnderwaterEffect)); } Water3UnderwaterEffect effect = (Water3UnderwaterEffect)cam.gameObject.GetComponent(typeof(Water3UnderwaterEffect)); if(effect) { effect.enabled = true; effect.m_Water = this; } underWater = true; } else { Water3UnderwaterEffect effect = (Water3UnderwaterEffect)cam.gameObject.GetComponent(typeof(Water3UnderwaterEffect)); if(effect && effect.enabled) { effect.enabled = false; } if(realtime2DReflection) { // we want realtime reflection (need an extra camera render) Shader.EnableKeyword("RT_REFLECTION_ON"); Shader.DisableKeyword("RT_REFLECTION_OFF"); // Reflect camera around reflection plane float d = -Vector3.Dot (normal, pos) - m_ClipPlaneOffset; Vector4 reflectionPlane = new Vector4 (normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.zero; CalculateReflectionMatrix (ref reflection, 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 = CameraSpacePlane( reflectionCamera, pos, normal, 1.0f ); Matrix4x4 projection = cam.projectionMatrix; CalculateObliqueMatrix (ref projection, clipPlane); reflectionCamera.projectionMatrix = projection; reflectionCamera.depthTextureMode = DepthTextureMode.None; reflectionCamera.renderingPath = RenderingPath.Forward; reflectionCamera.cullingMask = ~(1<<4) & m_ReflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; GL.SetRevertBackfacing (true); reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); reflectionCamera.Render(); reflectionCamera.transform.position = oldpos; GL.SetRevertBackfacing (false); renderer.sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture ); } else { // we "just" want a static cubemap reflection // NOTE: this can actually look better if there is a // lot of displacement going on ... Shader.EnableKeyword("RT_REFLECTION_OFF"); Shader.DisableKeyword("RT_REFLECTION_ON"); } } } // restore pixel light count if(m_DisablePixelLights) QualitySettings.pixelLightCount = oldPixelLightCount; if(lightTransform) renderer.sharedMaterial.SetVector("_WorldLightDir", lightTransform.forward); if(!m_DepthTexturesSupported) autoEdgeBlend = false; if(waterDisplacement) { Shader.EnableKeyword("WATER_DISPLACEMENT_ON"); Shader.DisableKeyword("WATER_DISPLACEMENT_OFF"); } else { Shader.DisableKeyword("WATER_DISPLACEMENT_ON"); Shader.EnableKeyword("WATER_DISPLACEMENT_OFF"); } if(autoEdgeBlend) { Shader.EnableKeyword("EDGEBLEND_ON"); Shader.DisableKeyword("EDGEBLEND_OFF"); } else { Shader.DisableKeyword("EDGEBLEND_ON"); Shader.EnableKeyword("EDGEBLEND_OFF"); } if(refractionMask) { Shader.EnableKeyword("REFRACTION_MASK_ON"); Shader.DisableKeyword("REFRACTION_MASK_OFF"); } else { Shader.DisableKeyword("REFRACTION_MASK_ON"); Shader.EnableKeyword("REFRACTION_MASK_OFF"); } if(underWater) { // TODO: cleanup underwater implementation // we need depth texture support here if(cam) cam.depthTextureMode |= DepthTextureMode.Depth; renderer.sharedMaterial.shader.maximumLOD = 50; } else if(mode == WaterMode.Indie) { renderer.sharedMaterial.shader.maximumLOD = 100; } else { if(mode == WaterMode.Optimized) renderer.sharedMaterial.shader.maximumLOD = 400; else renderer.sharedMaterial.shader.maximumLOD = mode > WaterMode.FastAndNoRefraction ? 500 : 300; if(autoEdgeBlend) { // soft water intersection requires depth textures if(cam) cam.depthTextureMode |= DepthTextureMode.Depth; } } s_InsideWater = false; }
// On-demand create any objects we need for water void CreateWaterObjects(/*Camera currentCamera, out Camera reflectionCamera, out Camera refractionCamera*/) { WaterMode mode = GetWaterMode(); //reflectionCamera = null; //refractionCamera = null; if (mode >= WaterMode.Reflective) { // Reflection render texture if (!m_ReflectionTexture || m_OldReflectionTextureSize != textureSize) { if (m_ReflectionTexture) { DestroyImmediate(m_ReflectionTexture); } m_ReflectionTexture = new RenderTexture(textureSize, textureSize, 16); m_ReflectionTexture.name = "__WaterReflection" + GetInstanceID(); m_ReflectionTexture.isPowerOfTwo = true; m_ReflectionTexture.hideFlags = HideFlags.DontSave; m_OldReflectionTextureSize = textureSize; } // Camera for reflection //m_ReflectionCameras.TryGetValue(currentCamera, out reflectionCamera); if (!reflectionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO { GameObject go = new GameObject("Water Refl Camera id" + GetInstanceID() + " for " /*+ currentCamera.GetInstanceID()*/, typeof(Camera), typeof(Skybox)); reflectionCamera = go.GetComponent <Camera>(); reflectionCamera.enabled = false; reflectionCamera.transform.position = transform.position; reflectionCamera.transform.rotation = transform.rotation; //reflectionCamera.gameObject.AddComponent<FlareLayer>(); go.hideFlags = HideFlags.HideAndDontSave; #if UNITY_EDITOR // print("Water Refl Camera id"); #endif //m_ReflectionCameras[currentCamera] = reflectionCamera; } } /*if (mode >= WaterMode.Refractive) * { * // Refraction render texture * if (!m_RefractionTexture || m_OldRefractionTextureSize != textureSize) * { * if (m_RefractionTexture) * { * DestroyImmediate(m_RefractionTexture); * } * m_RefractionTexture = new RenderTexture(textureSize, textureSize, 16); * m_RefractionTexture.name = "__WaterRefraction" + GetInstanceID(); * m_RefractionTexture.isPowerOfTwo = true; * m_RefractionTexture.hideFlags = HideFlags.DontSave; * m_OldRefractionTextureSize = textureSize; * } * * // Camera for refraction * //m_RefractionCameras.TryGetValue(currentCamera, out refractionCamera); * if (!refractionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO * { * GameObject go = * new GameObject("Water Refr Camera id" + GetInstanceID() + " for " /*+ currentCamera.GetInstanceID()* /, * typeof(Camera), typeof(Skybox)); * refractionCamera = go.GetComponent<Camera>(); * refractionCamera.enabled = false; * refractionCamera.transform.position = transform.position; * refractionCamera.transform.rotation = transform.rotation; * //refractionCamera.gameObject.AddComponent<FlareLayer>(); * go.hideFlags = HideFlags.HideAndDontSave; #if UNITY_EDITOR * print("Water Refr Camera id"); #endif * * //m_RefractionCameras[currentCamera] = refractionCamera; * } * }*/ }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { _renderer = GetComponent <Renderer>(); if (!enabled || !_renderer || !_renderer.sharedMaterial || !_renderer.enabled || (!Application.isPlaying && !runWhenNotPlaying)) { return; } Camera cam = Camera.current; if (!cam) { return; } // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera, refractionCamera; CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); // 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/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (disablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(cam, reflectionCamera); UpdateCameraModes(cam, refractionCamera); // Render reflection if needed if (mode >= WaterMode.Reflective) { if (cam.stereoEnabled) { if (cam.stereoTargetEye == StereoTargetEyeMask.Both || cam.stereoTargetEye == StereoTargetEyeMask.Left) { Vector3 eyePos = cam.transform.TransformPoint(new Vector3(-0.5f * cam.stereoSeparation, 0, 0)); Matrix4x4 projectionMatrix = cam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left); RenderReflection(reflectionCamera, m_ReflectionTexture0, eyePos, cam.transform.rotation, projectionMatrix); GetRendererMaterial().SetTexture("_ReflectionTex0", m_ReflectionTexture0); } if (cam.stereoTargetEye == StereoTargetEyeMask.Both || cam.stereoTargetEye == StereoTargetEyeMask.Right) { Vector3 eyePos = cam.transform.TransformPoint(new Vector3(0.5f * cam.stereoSeparation, 0, 0)); Matrix4x4 projectionMatrix = cam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right); RenderReflection(reflectionCamera, m_ReflectionTexture1, eyePos, cam.transform.rotation, projectionMatrix); GetRendererMaterial().SetTexture("_ReflectionTex1", m_ReflectionTexture1); } } else { RenderReflection(reflectionCamera, m_ReflectionTexture0, cam.transform.position, cam.transform.rotation, cam.projectionMatrix); GetRendererMaterial().SetTexture("_ReflectionTex0", m_ReflectionTexture0); } } // Render refraction if (mode >= WaterMode.Refractive) { if (cam.stereoEnabled) { if (cam.stereoTargetEye == StereoTargetEyeMask.Both || cam.stereoTargetEye == StereoTargetEyeMask.Left) { Vector3 eyePos = cam.transform.TransformPoint(new Vector3(-0.5f * cam.stereoSeparation, 0, 0)); Matrix4x4 projectionMatrix = cam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Left); refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; refractionCamera.transform.position = eyePos; refractionCamera.transform.rotation = cam.transform.rotation; cam.projectionMatrix = projectionMatrix; Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); refractionCamera.cullingMatrix = projectionMatrix * cam.worldToCameraMatrix; refractionCamera.cullingMask = ~(1 << 4) & refractLayers.value; // never render water layer refractionCamera.targetTexture = m_RefractionTexture0; refractionCamera.Render(); GetRendererMaterial().SetTexture("_RefractionTex0", m_RefractionTexture0); } if (cam.stereoTargetEye == StereoTargetEyeMask.Both || cam.stereoTargetEye == StereoTargetEyeMask.Right) { Vector3 eyePos = cam.transform.TransformPoint(new Vector3(0.5f * cam.stereoSeparation, 0, 0)); Matrix4x4 projectionMatrix = cam.GetStereoProjectionMatrix(Camera.StereoscopicEye.Right); refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; refractionCamera.transform.position = eyePos; refractionCamera.transform.rotation = cam.transform.rotation; cam.projectionMatrix = projectionMatrix; Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); refractionCamera.cullingMatrix = projectionMatrix * cam.worldToCameraMatrix; refractionCamera.cullingMask = ~(1 << 4) & refractLayers.value; // never render water layer refractionCamera.targetTexture = m_RefractionTexture1; refractionCamera.Render(); GetRendererMaterial().SetTexture("_RefractionTex1", m_RefractionTexture1); } } else { refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); // Set custom culling matrix from the current camera refractionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix; refractionCamera.cullingMask = ~(1 << 4) & refractLayers.value; // never render water layer refractionCamera.targetTexture = m_RefractionTexture0; refractionCamera.transform.position = cam.transform.position; refractionCamera.transform.rotation = cam.transform.rotation; refractionCamera.Render(); GetRendererMaterial().SetTexture("_RefractionTex0", m_RefractionTexture0); } } // Restore pixel light count if (disablePixelLights) { QualitySettings.pixelLightCount = oldPixelLightCount; } // Setup shader keywords based on water mode switch (mode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! void Update() { //check if need to render reflection texture Renderer[] childRenderers = GetComponentsInChildren <Renderer>(); if (!enabled || childRenderers.Length == 0) { return; } bool needRender = false; for (int i = 0; i < childRenderers.Length; ++i) { if (childRenderers[i].enabled) { needRender = true; } } if (!needRender) { return; } Camera cam = Camera.main; // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera, refractionCamera; CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); // find out the reflection plane: position and normal in world space Vector3 pos = transform.position; Vector3 normal = transform.up; Vector3 dir = cam.transform.position - pos; int mutilplyFactor = 1; if (Vector3.Dot(dir, normal) < 0.0f) { mutilplyFactor = -1; } UpdateCameraModes(cam, reflectionCamera); UpdateCameraModes(cam, refractionCamera); // Render reflection if needed if (mode >= WaterMode.Reflective && mutilplyFactor > 0) { // 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 = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, 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 = CameraSpacePlane(reflectionCamera, pos, normal, mutilplyFactor); //** reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); //** // Set custom culling matrix from the current camera //reflectionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix; reflectionCamera.cullingMask = ~(1 << 4) & reflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; //reflectionCamera.clearFlags = CameraClearFlags.SolidColor; //reflectionCamera.backgroundColor = new Color(0,0,0,0); bool oldCulling = GL.invertCulling; GL.invertCulling = !oldCulling; reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(euler.x, euler.y, euler.z); reflectionCamera.Render(); reflectionCamera.transform.position = oldpos; GL.invertCulling = oldCulling; SetRenderTexture(childRenderers, "_ReflectionTex", m_ReflectionTexture); } // Render refraction if (mode >= WaterMode.Refractive) { refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1 * mutilplyFactor); refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); // Set custom culling matrix from the current camera //refractionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix; refractionCamera.cullingMask = ~(1 << 4) & refractLayers.value; // never render water layer refractionCamera.targetTexture = m_RefractionTexture; refractionCamera.transform.position = cam.transform.position; refractionCamera.transform.rotation = cam.transform.rotation; refractionCamera.Render(); SetRenderTexture(childRenderers, "_RefractionTex", m_RefractionTexture); } // Setup shader keywords based on water mode switch (mode) { case WaterMode.SolidColor: Shader.EnableKeyword("WATER_SOLID"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SOLID"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SOLID"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; }
// On-demand create any objects we need for water void CreateWaterObjects(Camera currentCamera, out Camera reflectionCamera, out Camera refractionCamera) { WaterMode mode = GetWaterMode(); reflectionCamera = null; refractionCamera = null; if ((mode & WaterMode.Reflective) == WaterMode.Reflective) { // Reflection render texture if (!p.reflTex || p.oldReflTexSize != p.textureSize) { if (p.reflTex) { DestroyImmediate(p.reflTex); } p.reflTex = new RenderTexture(p.textureSize, p.textureSize, 16); p.reflTex.name = "__WaterReflection" + GetInstanceID(); p.reflTex.isPowerOfTwo = true; p.reflTex.hideFlags = HideFlags.DontSave; p.oldReflTexSize = p.textureSize; } // Camera for reflection p.reflCams.TryGetValue(currentCamera, out reflectionCamera); if (!reflectionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO { GameObject go = new GameObject("Water Refl Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox)); reflectionCamera = go.GetComponent <Camera>(); reflectionCamera.enabled = false; reflectionCamera.transform.position = transform.position; reflectionCamera.transform.rotation = transform.rotation; reflectionCamera.gameObject.AddComponent <FlareLayer>(); go.hideFlags = hideObjects ? HideFlags.HideAndDontSave : HideFlags.DontSave; p.reflCams[currentCamera] = reflectionCamera; } } if ((mode & WaterMode.Refractive) == WaterMode.Refractive) { // Refraction render texture if (!p.refrTex || p.oldRefrTexSize != p.textureSize) { if (p.refrTex) { DestroyImmediate(p.refrTex); } p.refrTex = new RenderTexture(p.textureSize, p.textureSize, 16); p.refrTex.name = "__WaterRefraction" + GetInstanceID(); p.refrTex.isPowerOfTwo = true; p.refrTex.hideFlags = HideFlags.DontSave; p.oldRefrTexSize = p.textureSize; } // Camera for refraction p.refrCams.TryGetValue(currentCamera, out refractionCamera); if (!refractionCamera) // catch both not-in-dictionary and in-dictionary-but-deleted-GO { GameObject go = new GameObject("Water Refr Camera id" + GetInstanceID() + " for " + currentCamera.GetInstanceID(), typeof(Camera), typeof(Skybox)); refractionCamera = go.GetComponent <Camera>(); refractionCamera.enabled = false; refractionCamera.transform.position = transform.position; refractionCamera.transform.rotation = transform.rotation; refractionCamera.gameObject.AddComponent <FlareLayer>(); go.hideFlags = hideObjects ? HideFlags.HideAndDontSave : HideFlags.DontSave; p.refrCams[currentCamera] = refractionCamera; } } }
private void CreateWaterObjects(Camera currentCamera, out Camera reflectionCamera, out Camera refractionCamera) { //IL_005f: Unknown result type (might be due to invalid IL or missing references) //IL_0069: Expected O, but got Unknown //IL_011f: Unknown result type (might be due to invalid IL or missing references) //IL_0125: Expected O, but got Unknown //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0159: Unknown result type (might be due to invalid IL or missing references) //IL_01eb: Unknown result type (might be due to invalid IL or missing references) //IL_01f5: Expected O, but got Unknown //IL_02ab: Unknown result type (might be due to invalid IL or missing references) //IL_02b1: Expected O, but got Unknown //IL_02ce: Unknown result type (might be due to invalid IL or missing references) //IL_02e5: Unknown result type (might be due to invalid IL or missing references) WaterMode waterMode = GetWaterMode(); reflectionCamera = null; refractionCamera = null; if (waterMode >= WaterMode.Reflective) { if (!Object.op_Implicit(m_ReflectionTexture) || m_OldReflectionTextureSize != textureSize) { if (Object.op_Implicit(m_ReflectionTexture)) { Object.DestroyImmediate(m_ReflectionTexture); } m_ReflectionTexture = new RenderTexture(textureSize, textureSize, 16); m_ReflectionTexture.set_name("__WaterReflection" + this.GetInstanceID()); m_ReflectionTexture.set_isPowerOfTwo(true); m_ReflectionTexture.set_hideFlags(52); m_OldReflectionTextureSize = textureSize; } m_ReflectionCameras.TryGetValue(currentCamera, out reflectionCamera); if (!Object.op_Implicit(reflectionCamera)) { GameObject val = new GameObject("Water Refl Camera id" + this.GetInstanceID() + " for " + currentCamera.GetInstanceID(), new Type[2] { typeof(Camera), typeof(Skybox) }); reflectionCamera = val.GetComponent <Camera>(); reflectionCamera.set_enabled(false); reflectionCamera.get_transform().set_position(this.get_transform().get_position()); reflectionCamera.get_transform().set_rotation(this.get_transform().get_rotation()); reflectionCamera.get_gameObject().AddComponent <FlareLayer>(); val.set_hideFlags(61); m_ReflectionCameras[currentCamera] = reflectionCamera; if (TurnOffWaterOcclusion) { reflectionCamera.set_useOcclusionCulling(false); } } } if (waterMode >= WaterMode.Refractive) { if (!Object.op_Implicit(m_RefractionTexture) || m_OldRefractionTextureSize != textureSize) { if (Object.op_Implicit(m_RefractionTexture)) { Object.DestroyImmediate(m_RefractionTexture); } m_RefractionTexture = new RenderTexture(textureSize, textureSize, 16); m_RefractionTexture.set_name("__WaterRefraction" + this.GetInstanceID()); m_RefractionTexture.set_isPowerOfTwo(true); m_RefractionTexture.set_hideFlags(52); m_OldRefractionTextureSize = textureSize; } m_RefractionCameras.TryGetValue(currentCamera, out refractionCamera); if (!Object.op_Implicit(refractionCamera)) { GameObject val2 = new GameObject("Water Refr Camera id" + this.GetInstanceID() + " for " + currentCamera.GetInstanceID(), new Type[2] { typeof(Camera), typeof(Skybox) }); refractionCamera = val2.GetComponent <Camera>(); refractionCamera.set_enabled(false); refractionCamera.get_transform().set_position(this.get_transform().get_position()); refractionCamera.get_transform().set_rotation(this.get_transform().get_rotation()); refractionCamera.get_gameObject().AddComponent <FlareLayer>(); val2.set_hideFlags(61); m_RefractionCameras[currentCamera] = refractionCamera; if (TurnOffWaterOcclusion) { reflectionCamera.set_useOcclusionCulling(false); } } } }
} //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_002b: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_0037: Unknown result type (might be due to invalid IL or missing references) public void OnWillRenderObject() { //IL_0088: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Unknown result type (might be due to invalid IL or missing references) //IL_0095: Unknown result type (might be due to invalid IL or missing references) //IL_009a: Unknown result type (might be due to invalid IL or missing references) //IL_00cb: Unknown result type (might be due to invalid IL or missing references) //IL_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00fc: Unknown result type (might be due to invalid IL or missing references) //IL_0101: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_0112: Unknown result type (might be due to invalid IL or missing references) //IL_0117: Unknown result type (might be due to invalid IL or missing references) //IL_011b: Unknown result type (might be due to invalid IL or missing references) //IL_011d: Unknown result type (might be due to invalid IL or missing references) //IL_0122: Unknown result type (might be due to invalid IL or missing references) //IL_0126: Unknown result type (might be due to invalid IL or missing references) //IL_012b: Unknown result type (might be due to invalid IL or missing references) //IL_012d: Unknown result type (might be due to invalid IL or missing references) //IL_0139: Unknown result type (might be due to invalid IL or missing references) //IL_013b: Unknown result type (might be due to invalid IL or missing references) //IL_0142: Unknown result type (might be due to invalid IL or missing references) //IL_0147: Unknown result type (might be due to invalid IL or missing references) //IL_014b: Unknown result type (might be due to invalid IL or missing references) //IL_014d: Unknown result type (might be due to invalid IL or missing references) //IL_018e: Unknown result type (might be due to invalid IL or missing references) //IL_019b: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: Unknown result type (might be due to invalid IL or missing references) //IL_01be: Unknown result type (might be due to invalid IL or missing references) //IL_01d4: Unknown result type (might be due to invalid IL or missing references) //IL_0206: Unknown result type (might be due to invalid IL or missing references) //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0214: Unknown result type (might be due to invalid IL or missing references) //IL_021b: Unknown result type (might be due to invalid IL or missing references) //IL_0220: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_0226: Unknown result type (might be due to invalid IL or missing references) //IL_025c: Unknown result type (might be due to invalid IL or missing references) //IL_0272: Unknown result type (might be due to invalid IL or missing references) if (this.get_enabled() && Object.op_Implicit(this.GetComponent <Renderer>()) && Object.op_Implicit(this.GetComponent <Renderer>().get_sharedMaterial()) && this.GetComponent <Renderer>().get_enabled()) { Camera current = Camera.get_current(); if (Object.op_Implicit(current) && !s_InsideWater) { s_InsideWater = true; m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode waterMode = GetWaterMode(); CreateWaterObjects(current, out Camera reflectionCamera, out Camera refractionCamera); Vector3 position = this.get_transform().get_position(); Vector3 up = this.get_transform().get_up(); int pixelLightCount = QualitySettings.get_pixelLightCount(); if (disablePixelLights) { QualitySettings.set_pixelLightCount(0); } UpdateCameraModes(current, reflectionCamera); UpdateCameraModes(current, refractionCamera); if (waterMode >= WaterMode.Reflective) { float num = 0f - Vector3.Dot(up, position) - clipPlaneOffset; Vector4 plane = default(Vector4); plane._002Ector(up.x, up.y, up.z, num); Matrix4x4 reflectionMat = Matrix4x4.get_zero(); CalculateReflectionMatrix(ref reflectionMat, plane); Vector3 position2 = current.get_transform().get_position(); Vector3 position3 = reflectionMat.MultiplyPoint(position2); reflectionCamera.set_worldToCameraMatrix(current.get_worldToCameraMatrix() * reflectionMat); Vector4 val = CameraSpacePlane(reflectionCamera, position, up, 1f); reflectionCamera.set_projectionMatrix(current.CalculateObliqueMatrix(val)); reflectionCamera.set_cullingMask(-17 & reflectLayers.get_value()); reflectionCamera.set_targetTexture(m_ReflectionTexture); bool invertCulling = GL.get_invertCulling(); GL.set_invertCulling(!invertCulling); reflectionCamera.get_transform().set_position(position3); Vector3 eulerAngles = current.get_transform().get_eulerAngles(); reflectionCamera.get_transform().set_eulerAngles(new Vector3(0f - eulerAngles.x, eulerAngles.y, eulerAngles.z)); reflectionCamera.Render(); reflectionCamera.get_transform().set_position(position2); GL.set_invertCulling(invertCulling); this.GetComponent <Renderer>().get_sharedMaterial().SetTexture("_ReflectionTex", m_ReflectionTexture); } if (waterMode >= WaterMode.Refractive) { refractionCamera.set_worldToCameraMatrix(current.get_worldToCameraMatrix()); Vector4 val2 = CameraSpacePlane(refractionCamera, position, up, -1f); refractionCamera.set_projectionMatrix(current.CalculateObliqueMatrix(val2)); refractionCamera.set_cullingMask(-17 & refractLayers.get_value()); refractionCamera.set_targetTexture(m_RefractionTexture); refractionCamera.get_transform().set_position(current.get_transform().get_position()); refractionCamera.get_transform().set_rotation(current.get_transform().get_rotation()); refractionCamera.Render(); this.GetComponent <Renderer>().get_sharedMaterial().SetTexture("_RefractionTex", m_RefractionTexture); } if (disablePixelLights) { QualitySettings.set_pixelLightCount(pixelLightCount); } switch (waterMode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; } } }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { if (!enabled) { return; } if (!renderer.sharedMaterial) { return; } Camera cam = Camera.current; if (!cam) { return; } // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; bool underWater = false; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera; CreateWaterObjects(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/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (m_DisablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(cam, reflectionCamera); // Render reflection if needed if (mode >= WaterMode.FastAndNoRefraction) { // this should actually be accompanied along with a // special image effect, blurring out the scene etc. if (IsUnderwater(cam)) { /* * reflectionCamera.depthTextureMode = DepthTextureMode.None; * reflectionCamera.renderingPath = RenderingPath.Forward; * * reflectionCamera.transform.position = cam.transform.position; * reflectionCamera.transform.rotation = cam.transform.rotation; * reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; * reflectionCamera.targetTexture = m_ReflectionTexture; * reflectionCamera.cullingMask = ~(1<<4) & m_ReflectLayers.value; // never render water layer * reflectionCamera.projectionMatrix = cam.projectionMatrix; * * reflectionCamera.Render(); */ if (Camera.main == cam && !cam.gameObject.GetComponent(typeof(Water3UnderwaterEffect))) { cam.gameObject.AddComponent(typeof(Water3UnderwaterEffect)); } Water3UnderwaterEffect effect = (Water3UnderwaterEffect)cam.gameObject.GetComponent(typeof(Water3UnderwaterEffect)); if (effect) { effect.enabled = true; effect.m_Water = this; } underWater = true; } else { Water3UnderwaterEffect effect = (Water3UnderwaterEffect)cam.gameObject.GetComponent(typeof(Water3UnderwaterEffect)); if (effect && effect.enabled) { effect.enabled = false; } if (realtime2DReflection) { // we want realtime reflection (need an extra camera render) Shader.EnableKeyword("RT_REFLECTION_ON"); Shader.DisableKeyword("RT_REFLECTION_OFF"); // Reflect camera around reflection plane float d = -Vector3.Dot(normal, pos) - m_ClipPlaneOffset; Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, 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 = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); Matrix4x4 projection = cam.projectionMatrix; CalculateObliqueMatrix(ref projection, clipPlane); reflectionCamera.projectionMatrix = projection; reflectionCamera.depthTextureMode = DepthTextureMode.None; reflectionCamera.renderingPath = RenderingPath.Forward; reflectionCamera.cullingMask = ~(1 << 4) & m_ReflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; GL.SetRevertBackfacing(true); reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); reflectionCamera.Render(); reflectionCamera.transform.position = oldpos; GL.SetRevertBackfacing(false); renderer.sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture); } else { // we "just" want a static cubemap reflection // NOTE: this can actually look better if there is a // lot of displacement going on ... Shader.EnableKeyword("RT_REFLECTION_OFF"); Shader.DisableKeyword("RT_REFLECTION_ON"); } } } // restore pixel light count if (m_DisablePixelLights) { QualitySettings.pixelLightCount = oldPixelLightCount; } if (lightTransform) { renderer.sharedMaterial.SetVector("_WorldLightDir", lightTransform.forward); } if (!m_DepthTexturesSupported) { autoEdgeBlend = false; } if (waterDisplacement) { Shader.EnableKeyword("WATER_DISPLACEMENT_ON"); Shader.DisableKeyword("WATER_DISPLACEMENT_OFF"); } else { Shader.DisableKeyword("WATER_DISPLACEMENT_ON"); Shader.EnableKeyword("WATER_DISPLACEMENT_OFF"); } if (autoEdgeBlend) { Shader.EnableKeyword("EDGEBLEND_ON"); Shader.DisableKeyword("EDGEBLEND_OFF"); } else { Shader.DisableKeyword("EDGEBLEND_ON"); Shader.EnableKeyword("EDGEBLEND_OFF"); } if (refractionMask) { Shader.EnableKeyword("REFRACTION_MASK_ON"); Shader.DisableKeyword("REFRACTION_MASK_OFF"); } else { Shader.DisableKeyword("REFRACTION_MASK_ON"); Shader.EnableKeyword("REFRACTION_MASK_OFF"); } if (underWater) { // TODO: cleanup underwater implementation // we need depth texture support here if (cam) { cam.depthTextureMode |= DepthTextureMode.Depth; } renderer.sharedMaterial.shader.maximumLOD = 50; } else if (mode == WaterMode.Indie) { renderer.sharedMaterial.shader.maximumLOD = 100; } else { if (mode == WaterMode.Optimized) { renderer.sharedMaterial.shader.maximumLOD = 400; } else { renderer.sharedMaterial.shader.maximumLOD = mode > WaterMode.FastAndNoRefraction ? 500 : 300; } if (autoEdgeBlend) { // soft water intersection requires depth textures if (cam) { cam.depthTextureMode |= DepthTextureMode.Depth; } } } s_InsideWater = false; }
// This is called when it's known that the object will be rendered by some // camera. We render reflections / refractions and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { if (!enabled || !GetComponent <Renderer>() || !GetComponent <Renderer>().sharedMaterial || !GetComponent <Renderer>().enabled) { return; } Camera cam = Camera.current; if (!cam) { return; } // Safeguard from recursive water reflections. if (s_InsideWater) { return; } s_InsideWater = true; // Actual water rendering mode depends on both the current setting AND // the hardware support. There's no point in rendering refraction textures // if they won't be visible in the end. m_HardwareWaterSupport = FindHardwareWaterSupport(); WaterMode mode = GetWaterMode(); Camera reflectionCamera, refractionCamera; CreateWaterObjects(cam, out reflectionCamera, out refractionCamera); // 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/refraction int oldPixelLightCount = QualitySettings.pixelLightCount; if (disablePixelLights) { QualitySettings.pixelLightCount = 0; } UpdateCameraModes(cam, reflectionCamera); UpdateCameraModes(cam, refractionCamera); // Render reflection if needed if (mode >= WaterMode.Reflective) { // 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 = Matrix4x4.zero; CalculateReflectionMatrix(ref reflection, 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 = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); reflectionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); // Set custom culling matrix from the current camera reflectionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix; reflectionCamera.cullingMask = ~(1 << 4) & reflectLayers.value; // never render water layer reflectionCamera.targetTexture = m_ReflectionTexture; bool oldCulling = GL.invertCulling; GL.invertCulling = !oldCulling; reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); try { reflectionCamera.Render(); } catch { //swallow rendering errors } reflectionCamera.transform.position = oldpos; GL.invertCulling = oldCulling; GetComponent <Renderer>().sharedMaterial.SetTexture("_ReflectionTex", m_ReflectionTexture); } // Render refraction if (mode >= WaterMode.Refractive) { refractionCamera.worldToCameraMatrix = cam.worldToCameraMatrix; // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything below/above it for free. Vector4 clipPlane = CameraSpacePlane(refractionCamera, pos, normal, -1.0f); refractionCamera.projectionMatrix = cam.CalculateObliqueMatrix(clipPlane); // Set custom culling matrix from the current camera refractionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix; refractionCamera.cullingMask = ~(1 << 4) & refractLayers.value; // never render water layer refractionCamera.targetTexture = m_RefractionTexture; refractionCamera.transform.position = cam.transform.position; refractionCamera.transform.rotation = cam.transform.rotation; refractionCamera.Render(); GetComponent <Renderer>().sharedMaterial.SetTexture("_RefractionTex", m_RefractionTexture); } // Restore pixel light count if (disablePixelLights) { QualitySettings.pixelLightCount = oldPixelLightCount; } // Setup shader keywords based on water mode switch (mode) { case WaterMode.Simple: Shader.EnableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Reflective: Shader.DisableKeyword("WATER_SIMPLE"); Shader.EnableKeyword("WATER_REFLECTIVE"); Shader.DisableKeyword("WATER_REFRACTIVE"); break; case WaterMode.Refractive: Shader.DisableKeyword("WATER_SIMPLE"); Shader.DisableKeyword("WATER_REFLECTIVE"); Shader.EnableKeyword("WATER_REFRACTIVE"); break; } s_InsideWater = false; }
// This just sets up some matrices in the material; for really // old cards to make water texture scroll. void Update() { if( !GetComponent<Renderer>() ) return; if(usefullData.lowTechnologie) { float theTime = Time.time; float moveWater = Mathf.PingPong(theTime * LTspeed, 100) * 0.15f; gameObject.GetComponent<Renderer>().material.SetTextureOffset("_MainTex", new Vector2( moveWater, moveWater )); // gameObject.renderer.material.SetColor("_HorizonColor",new Color(1.0f,1.0f,1.0f,LTalpha)); if(liner!=null) { gameObject.GetComponent<Renderer>().material.SetColor("_HorizonColor",liner.GetComponent<Renderer>().material.color); } gameObject.GetComponent<Renderer>().material.SetTextureScale("_MainTex", new Vector2(LTwaveScale, LTwaveScale)); // return; } else { Material mat = GetComponent<Renderer>().sharedMaterial; if( !mat ) return; //TEST TEST_mode_2D_iso if(Camera.main.orthographic) { if(GetWaterMode()==WaterMode.Refractive) { m_WaterMode = WaterMode.Simple; mat.SetColor("_HorizonColor", new Color(0.0f,1.0f,1.0f,1.0f)); } } else { if(GetWaterMode()==WaterMode.Simple) m_WaterMode = WaterMode.Refractive; if(usefullData.lowTechnologie) { m_WaterMode = WaterMode.Simple; mat.SetColor("_HorizonColor", new Color(1.0f,1.0f,1.0f,1.0f)); } } //END TEST_mode_2D_iso //Vector4 waveSpeed = mat.GetVector( "WaveSpeed" ); Vector4 waveSpeed = mat.GetVector( "WaveSpeed" ); //Vector4 waveSpeed = new Vector4(1.9f,0.9f,-1.6f,-0.7f); //mat.SetVector( "WaveSpeed",waveSpeed ); float waveScale = mat.GetFloat( "_WaveScale" ); //mat.SetFloat("_ReflDistort",0.1f ); //mat.SetFloat("_RefrDistort",0.2f ); Vector4 waveScale4 = new Vector4(waveScale, waveScale, waveScale * 0.4f, waveScale * 0.45f); // Time since level load, and do intermediate calculations with doubles double t = Time.timeSinceLevelLoad / 20.0; Vector4 offsetClamped = new Vector4( (float)System.Math.IEEERemainder(waveSpeed.x * waveScale4.x * t, 1.0), (float)System.Math.IEEERemainder(waveSpeed.y * waveScale4.y * t, 1.0), (float)System.Math.IEEERemainder(waveSpeed.z * waveScale4.z * t, 1.0), (float)System.Math.IEEERemainder(waveSpeed.w * waveScale4.w * t, 1.0) ); //print ("offsetClamped :"+offsetClamped); mat.SetVector( "_WaveOffset", offsetClamped ); mat.SetVector( "_WaveScale4", waveScale4 ); Vector3 waterSize = GetComponent<Renderer>().bounds.size; Vector3 scale = new Vector3( waterSize.x*waveScale4.x, waterSize.z*waveScale4.y, 1 ); Matrix4x4 scrollMatrix = Matrix4x4.TRS( new Vector3(offsetClamped.x,offsetClamped.y,0), Quaternion.identity, scale ); mat.SetMatrix( "_WaveMatrix", scrollMatrix ); scale = new Vector3( waterSize.x*waveScale4.z, waterSize.z*waveScale4.w, 1 ); scrollMatrix = Matrix4x4.TRS( new Vector3(offsetClamped.z,offsetClamped.w,0), Quaternion.identity, scale ); mat.SetMatrix( "_WaveMatrix2", scrollMatrix ); gameObject.GetComponent<Renderer>().material.SetVector("_LightPos",(Vector4) mainLight.transform.forward); if(mainLightConfiguration.m_hour<0) { gameObject.GetComponent<Renderer>().material.SetFloat("_azimut",-1); } else { gameObject.GetComponent<Renderer>().material.SetFloat("_azimut",1); } //print("HEURE " +mainLightConfiguration.m_hour + " AZIMUT " +mainLightConfiguration.m_azimut); float scaleGeneral = gameObject.transform.lossyScale.x; { // if( initWave>0) // gameObject.renderer.material.SetFloat("_WaveScale",initWave/scaleGeneral); // if( initRefrac>0) // gameObject.renderer.material.SetFloat("_ReflDistort",initRefrac/scaleGeneral); // if( initReflect>0) // gameObject.renderer.material.SetFloat("_RefrDistort",initReflect/scaleGeneral); } } }