/// <summary> /// Render the reflections. /// </summary> void RenderReflectionFor(Camera cam, Camera reflectCamera, OceanCameraSettings settings) { //UpdateSkyBox(cam, reflectCamera); Vector3 eulerA = cam.transform.eulerAngles; reflectCamera.transform.eulerAngles = new Vector3(-eulerA.x, eulerA.y, eulerA.z); reflectCamera.transform.position = cam.transform.position; float level = m_ocean.level; Vector3 pos = new Vector3(0, level, 0); Vector3 normal = Vector3.up; float d = -Vector3.Dot(normal, pos) - clipPlaneOffset; Vector4 reflectionPlane = new Vector4(normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.zero; reflection = CalculateReflectionMatrix(reflection, reflectionPlane); Vector3 oldPos = cam.transform.position; Vector3 newpos = reflection.MultiplyPoint(oldPos); reflectCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflection; Vector4 clipPlane = CameraSpacePlane(reflectCamera, pos, normal, 1.0f); Matrix4x4 projection = cam.projectionMatrix; projection = CalculateObliqueMatrix(projection, clipPlane); reflectCamera.projectionMatrix = projection; reflectCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); reflectCamera.cullingMask = GetReflectionLayermask(settings); reflectCamera.cullingMask = OceanUtility.HideLayer(reflectCamera.cullingMask, Ocean.OCEAN_LAYER); int oldPixelLightCount = QualitySettings.pixelLightCount; if (!pixelLightsInReflection) { QualitySettings.pixelLightCount = 0; } bool oldCulling = GL.invertCulling; GL.invertCulling = !oldCulling; reflectCamera.Render(); QualitySettings.pixelLightCount = oldPixelLightCount; GL.invertCulling = oldCulling; }
private void RenderReflectionFor(Camera cam, Camera reflectCamera, OceanCameraSettings settings) { Vector3 eulerAngles = cam.transform.eulerAngles; reflectCamera.transform.eulerAngles = new Vector3(-eulerAngles.x, eulerAngles.y, eulerAngles.z); reflectCamera.transform.position = cam.transform.position; float level = this.m_ocean.level; Vector3 vector = new Vector3(0f, level, 0f); Vector3 up = Vector3.up; float w = -Vector3.Dot(up, vector) - this.clipPlaneOffset; Vector4 plane = new Vector4(up.x, up.y, up.z, w); Matrix4x4 matrix4x = Matrix4x4.zero; matrix4x = this.CalculateReflectionMatrix(matrix4x, plane); Vector3 position = cam.transform.position; Vector3 position2 = matrix4x.MultiplyPoint(position); reflectCamera.worldToCameraMatrix = cam.worldToCameraMatrix * matrix4x; Vector4 clipPlane = this.CameraSpacePlane(reflectCamera, vector, up, 1f); Matrix4x4 matrix4x2 = cam.projectionMatrix; matrix4x2 = this.CalculateObliqueMatrix(matrix4x2, clipPlane); reflectCamera.projectionMatrix = matrix4x2; reflectCamera.transform.position = position2; Vector3 eulerAngles2 = cam.transform.eulerAngles; reflectCamera.transform.eulerAngles = new Vector3(-eulerAngles2.x, eulerAngles2.y, eulerAngles2.z); reflectCamera.cullingMask = this.GetReflectionLayermask(settings); reflectCamera.cullingMask = OceanUtility.HideLayer(reflectCamera.cullingMask, Ocean.OCEAN_LAYER); int pixelLightCount = QualitySettings.pixelLightCount; if (!this.pixelLightsInReflection) { QualitySettings.pixelLightCount = 0; } bool invertCulling = GL.invertCulling; GL.invertCulling = !invertCulling; if (ForestVR.Enabled) { } reflectCamera.Render(); QualitySettings.pixelLightCount = pixelLightCount; GL.invertCulling = invertCulling; }
/// <summary> /// Render the reflections. /// </summary> void RenderReflection(Camera reflectionCam, RenderTexture target, Vector3 position, Quaternion rotation, Matrix4x4 projection, OceanCameraSettings settings) { // Copy camera position/rotation/projection data into the reflectionCamera reflectionCam.ResetWorldToCameraMatrix(); reflectionCam.transform.position = position; reflectionCam.transform.rotation = rotation; reflectionCam.projectionMatrix = projection; reflectionCam.targetTexture = target; float level = m_ocean.level; // find out the reflection plane: position and normal in world space Vector3 pos = new Vector3(0, level, 0); Vector3 normal = Vector3.up; // Reflect camera around reflection plane Vector4 worldSpaceClipPlane = Plane(pos, normal); reflectionCam.worldToCameraMatrix *= CalculateReflectionMatrix(worldSpaceClipPlane); // Setup oblique projection matrix so that near plane is our reflection // plane. This way we clip everything behind it for free. Vector4 cameraSpaceClipPlane = CameraSpacePlane(reflectionCam, pos, normal); reflectionCam.projectionMatrix = reflectionCam.CalculateObliqueMatrix(cameraSpaceClipPlane); reflectionCam.cullingMask = GetReflectionLayermask(settings); reflectionCam.cullingMask = OceanUtility.HideLayer(reflectionCam.cullingMask, Ocean.OCEAN_LAYER); bool oldCulling = GL.invertCulling; GL.invertCulling = !oldCulling; NotifyOnEvent.Disable = true; reflectionCam.Render(); NotifyOnEvent.Disable = false; GL.invertCulling = oldCulling; reflectionCam.targetTexture = null; }
public override void RenderOceanDepth(GameObject go) { try { if (base.enabled) { Camera current = Camera.current; if (!(current == null)) { CameraData cameraData = this.m_ocean.FindCameraData(current); if (cameraData.depth == null) { cameraData.depth = new DepthData(); } if (!cameraData.depth.updated) { if (this.GetDisableUnderwater(cameraData.settings)) { Shader.DisableKeyword("CETO_UNDERWATER_ON"); cameraData.depth.updated = true; } else { Shader.EnableKeyword("CETO_UNDERWATER_ON"); if (SystemInfo.graphicsShaderLevel < 30) { Shader.SetGlobalTexture(Ocean.OCEAN_DEPTH_TEXTURE_NAME, Texture2D.whiteTexture); Shader.SetGlobalTexture(Ocean.DEPTH_GRAB_TEXTURE_NAME, Texture2D.whiteTexture); Shader.SetGlobalTexture(Ocean.NORMAL_FADE_TEXTURE_NAME, Texture2D.blackTexture); Shader.SetGlobalMatrix("Ceto_Camera_IVP", (current.projectionMatrix * current.worldToCameraMatrix).inverse); cameraData.depth.updated = true; } else if (this.depthMode == DEPTH_MODE.USE_DEPTH_BUFFER) { Shader.SetGlobalTexture(Ocean.OCEAN_DEPTH_TEXTURE_NAME, Texture2D.whiteTexture); current.depthTextureMode |= DepthTextureMode.Depth; current.depthTextureMode |= DepthTextureMode.DepthNormals; Shader.SetGlobalMatrix("Ceto_Camera_IVP", (current.projectionMatrix * current.worldToCameraMatrix).inverse); this.CreateRefractionCommand(current, cameraData.depth); cameraData.depth.updated = true; } else if (this.depthMode == DEPTH_MODE.USE_OCEAN_DEPTH_PASS) { Shader.SetGlobalTexture(Ocean.DEPTH_GRAB_TEXTURE_NAME, Texture2D.whiteTexture); Shader.SetGlobalTexture(Ocean.NORMAL_FADE_TEXTURE_NAME, Texture2D.blackTexture); this.CreateDepthCameraFor(current, cameraData.depth); this.CreateRefractionCommand(current, cameraData.depth); cameraData.depth.cam.cullingMask = this.GetOceanDepthsLayermask(cameraData.settings); cameraData.depth.cam.cullingMask = OceanUtility.HideLayer(cameraData.depth.cam.cullingMask, Ocean.OCEAN_LAYER); NotifyOnEvent.Disable = true; cameraData.depth.cam.RenderWithShader(this.oceanDepthSdr, "RenderType"); NotifyOnEvent.Disable = false; Shader.SetGlobalTexture(Ocean.OCEAN_DEPTH_TEXTURE_NAME, cameraData.depth.cam.targetTexture); cameraData.depth.updated = true; } } } } } } catch (Exception ex) { Ocean.LogError(ex.ToString()); base.WasError = true; base.enabled = false; } }
/// <summary> /// Render depth information about a object using a replacement shader. /// If the ocean renders into the depth buffer then the shader can not get /// depth info about what has been rendered under it as Unity will have already /// written the ocean mesh into depth buffer by then. /// Will also create the refraction grab if needed. /// </summary> public void RenderOceanDepth(GameObject go) { try { if (!enabled) { return; } Camera cam = Camera.current; if (cam == null) { return; } CameraData data = m_ocean.FindCameraData(cam); if (data.depth == null) { data.depth = new DepthData(); } if (data.depth.IsViewUpdated(cam)) { return; } //If this camera has disable the underwater turn it off in the shader and return. if (GetDisableUnderwater(data.settings)) { Shader.DisableKeyword("CETO_UNDERWATER_ON"); data.depth.SetViewAsUpdated(cam); return; } else { Shader.EnableKeyword("CETO_UNDERWATER_ON"); } if (/*cam.name == "SceneCamera" ||*/ SystemInfo.graphicsShaderLevel < 30) { //These texture will not be generated so zero to some that will not cause a issue if sampled. Shader.SetGlobalTexture(Ocean.OCEAN_DEPTH_TEXTURE_NAME0, Texture2D.whiteTexture); Shader.SetGlobalTexture(Ocean.OCEAN_DEPTH_TEXTURE_NAME1, Texture2D.whiteTexture); Shader.SetGlobalTexture(Ocean.DEPTH_GRAB_TEXTURE_NAME, Texture2D.whiteTexture); Shader.SetGlobalTexture(Ocean.NORMAL_FADE_TEXTURE_NAME, Texture2D.blackTexture); //If not using the ocean depths all thats needed is the IVP //to extract the world pos from the depth buffer. BindIVPMatrix(cam.projectionMatrix, cam.worldToCameraMatrix); data.depth.SetViewAsUpdated(cam); } else if (depthMode == DEPTH_MODE.USE_DEPTH_BUFFER) { //These texture will not be generated so zero to some that will not cause a issue if sampled. Shader.SetGlobalTexture(Ocean.OCEAN_DEPTH_TEXTURE_NAME0, Texture2D.whiteTexture); Shader.SetGlobalTexture(Ocean.OCEAN_DEPTH_TEXTURE_NAME1, Texture2D.whiteTexture); //Cam must have depth mode enabled to use depth buffer. cam.depthTextureMode |= DepthTextureMode.Depth; cam.depthTextureMode |= DepthTextureMode.DepthNormals; CreateRefractionCommand(cam, data.depth); //If not using the ocean depths all thats needed is the IVP //to extract the world pos from the depth buffer. BindIVPMatrix(cam.projectionMatrix, cam.worldToCameraMatrix); data.depth.SetViewAsUpdated(cam); } else if (depthMode == DEPTH_MODE.USE_OCEAN_DEPTH_PASS) { //These texture will not be generated so zero to some that will not cause a issue if sampled. Shader.SetGlobalTexture(Ocean.DEPTH_GRAB_TEXTURE_NAME, Texture2D.whiteTexture); Shader.SetGlobalTexture(Ocean.NORMAL_FADE_TEXTURE_NAME, Texture2D.blackTexture); CreateDepthCameraFor(cam, data.depth); CreateRefractionCommand(cam, data.depth); data.depth.cam.cullingMask = GetOceanDepthsLayermask(data.settings); data.depth.cam.cullingMask = OceanUtility.HideLayer(data.depth.cam.cullingMask, Ocean.OCEAN_LAYER); if (cam.stereoEnabled) { RenderSteroOceanDepth(data.depth, cam); } else { Shader.DisableKeyword("CETO_STERO_CAMERA"); RenderOceanDepth(data.depth, data.depth.target0, cam.transform.position, cam.transform.rotation, cam.projectionMatrix); Shader.SetGlobalTexture(Ocean.OCEAN_DEPTH_TEXTURE_NAME0, data.depth.target0); } data.depth.SetViewAsUpdated(cam); } } catch (Exception e) { Ocean.LogError(e.ToString()); WasError = true; enabled = false; } }
/// <summary> /// Render depth information about a object using a replacement shader. /// If the ocean renders into the depth buffer then the shader can not get /// depth info about what has been rendered under it as Unity will have already /// written the ocean mesh into depth buffer by then. /// Will also create the refraction grab if needed. /// </summary> public override void RenderOceanDepth(GameObject go) { try { if (!enabled) { return; } Camera cam = Camera.current; if (cam == null) { return; } CameraData data = m_ocean.FindCameraData(cam); if (data.depth == null) { data.depth = new DepthData(); } if (data.depth.updated) { return; } //zero the texture so if there is a issue the underwater effect will not screw up the rest of the rendering. Shader.SetGlobalTexture(Ocean.REFRACTION_GRAB_TEXTURE_NAME, Texture2D.blackTexture); Shader.SetGlobalTexture(Ocean.DEPTH_GRAB_TEXTURE_NAME, Texture2D.whiteTexture); Shader.SetGlobalTexture("Ceto_OceanDepth", Texture2D.whiteTexture); //If this camera has disable the underwater turn it off in the shader and return. if (GetDisableUnderwater(data.settings)) { Shader.DisableKeyword("CETO_UNDERWATER_ON"); data.depth.updated = true; return; } else { Shader.EnableKeyword("CETO_UNDERWATER_ON"); } if (cam.name == "SceneCamera" || SystemInfo.graphicsShaderLevel < 30) { //Adding command to scene camera is causing some problems and may as //well not use the ocean depth pass so its consistent between modes //so just bind something that wont cause a issue. //If not using the ocean depths all thats needed is the IVP //to extract the world pos from the depth buffer. Matrix4x4 ivp = cam.projectionMatrix * cam.worldToCameraMatrix; Shader.SetGlobalMatrix("Ceto_Camera_IVP", ivp.inverse); data.depth.updated = true; } else if (depthMode == DEPTH_MODE.USE_DEPTH_BUFFER) { //Cam must have depth mode enabled to use depth buffer. cam.depthTextureMode |= DepthTextureMode.Depth; //If not using the ocean depths all thats needed is the IVP //to extract the world pos from the depth buffer. Matrix4x4 ivp = cam.projectionMatrix * cam.worldToCameraMatrix; Shader.SetGlobalMatrix("Ceto_Camera_IVP", ivp.inverse); //Add the command to camera. //The default implementation will just grab the depth and the screen. CreateRefractionGrab(cam, data.depth); data.depth.updated = true; } else if (depthMode == DEPTH_MODE.USE_OCEAN_DEPTH_PASS) { CreateDepthCameraFor(cam, data.depth); CreateRefractionGrab(cam, data.depth); data.depth.cam.cullingMask = GetOceanDepthsLayermask(data.settings); data.depth.cam.cullingMask = OceanUtility.HideLayer(data.depth.cam.cullingMask, Ocean.OCEAN_LAYER); NotifyOnEvent.Disable = true; data.depth.cam.RenderWithShader(oceanDepthSdr, "RenderType"); NotifyOnEvent.Disable = false; Shader.SetGlobalTexture("Ceto_OceanDepth", data.depth.cam.targetTexture); data.depth.updated = true; } } catch (Exception e) { Ocean.LogError(e.ToString()); WasError = true; enabled = false; } }