void RenderReflectionAndRefraction() { //return; //camera.ResetWorldToCameraMatrix(); offscreenCam.enabled = true; int oldPixelLightCount = QualitySettings.pixelLightCount; QualitySettings.pixelLightCount = 0; Camera renderCamera = mycam; Matrix4x4 originalWorldToCam = renderCamera.worldToCameraMatrix; int cullingMask = renderCamera.cullingMask & ~(1 << LayerMask.NameToLayer("Water")); //Reflection pass Matrix4x4 reflection = Matrix4x4.zero; //TODO: Use local plane here, not global! CameraHelper.CalculateReflectionMatrix(ref reflection, new Vector4(0.0f, 1.0f, 0.0f, 0.0f)); offscreenCam.transform.position = reflection.MultiplyPoint(renderCamera.transform.position); offscreenCam.transform.rotation = renderCamera.transform.rotation; offscreenCam.transform.Rotate(0, 180, 0); offscreenCam.worldToCameraMatrix = originalWorldToCam * reflection; offscreenCam.cullingMask = cullingMask; offscreenCam.targetTexture = reflectionTexture; offscreenCam.clearFlags = renderCamera.clearFlags; //Need to reverse face culling for reflection pass, since the camera //is now flipped upside/down. GL.SetRevertBackfacing(false); Vector4 cameraSpaceClipPlane = CameraHelper.CameraSpacePlane(offscreenCam, Vector3.zero, Vector3.up, 1.0f); Matrix4x4 projection = renderCamera.projectionMatrix; Matrix4x4 obliqueProjection = projection; CameraHelper.CalculateObliqueMatrix(ref obliqueProjection, cameraSpaceClipPlane); //Do the actual render, with the near plane set as the clipping plane. See the //pro water source for details. offscreenCam.projectionMatrix = obliqueProjection; offscreenCam.Render(); GL.SetRevertBackfacing(false); //Refractionpass bool fog = RenderSettings.fog; Color fogColor = RenderSettings.fogColor; float fogDensity = RenderSettings.fogDensity; RenderSettings.fog = true; RenderSettings.fogColor = Color.grey; RenderSettings.fogDensity = waterDirtyness / 10; //TODO: If we want to use this as a refraction seen from under the seaplane, // the cameraclear should be skybox. offscreenCam.clearFlags = CameraClearFlags.Color; offscreenCam.backgroundColor = Color.grey; offscreenCam.targetTexture = refractionTexture; obliqueProjection = projection; offscreenCam.transform.position = renderCamera.transform.position; offscreenCam.transform.rotation = renderCamera.transform.rotation; offscreenCam.worldToCameraMatrix = originalWorldToCam; cameraSpaceClipPlane = CameraHelper.CameraSpacePlane(offscreenCam, Vector3.zero, Vector3.up, -1.0f); CameraHelper.CalculateObliqueMatrix(ref obliqueProjection, cameraSpaceClipPlane); offscreenCam.projectionMatrix = obliqueProjection; offscreenCam.Render(); RenderSettings.fog = fog; RenderSettings.fogColor = fogColor; RenderSettings.fogDensity = fogDensity; offscreenCam.projectionMatrix = projection; offscreenCam.targetTexture = null; QualitySettings.pixelLightCount = oldPixelLightCount; // camera.ResetWorldToCameraMatrix(); //GL.SetRevertBackfacing (true); }
void RenderReflectionAndRefraction() { Camera renderCamera = Camera.mainCamera; Matrix4x4 originalWorldToCam = renderCamera.worldToCameraMatrix; int cullingMask = ~(1 << 4) & renderLayers.value; ; //Reflection pass Matrix4x4 reflection = Matrix4x4.zero; //TODO: Use local plane here, not global! float d = -transform.position.y; offscreenCam.backgroundColor = RenderSettings.fogColor; CameraHelper.CalculateReflectionMatrix(ref reflection, new Vector4(0f, 1f, 0f, d)); offscreenCam.transform.position = reflection.MultiplyPoint(renderCamera.transform.position); offscreenCam.transform.rotation = renderCamera.transform.rotation; offscreenCam.worldToCameraMatrix = originalWorldToCam * reflection; offscreenCam.cullingMask = cullingMask; offscreenCam.targetTexture = reflectionTexture; //Need to reverse face culling for reflection pass, since the camera //is now flipped upside/down. GL.SetRevertBackfacing(true); Vector4 cameraSpaceClipPlane = CameraHelper.CameraSpacePlane(offscreenCam, new Vector3(0.0f, transform.position.y, 0.0f), Vector3.up, 1.0f); Matrix4x4 projection = renderCamera.projectionMatrix; Matrix4x4 obliqueProjection = projection; offscreenCam.fieldOfView = renderCamera.fieldOfView; offscreenCam.aspect = renderCamera.aspect; CameraHelper.CalculateObliqueMatrix(ref obliqueProjection, cameraSpaceClipPlane); //Do the actual render, with the near plane set as the clipping plane. See the //pro water source for details. offscreenCam.projectionMatrix = obliqueProjection; if (!renderReflection) { offscreenCam.cullingMask = 0; } offscreenCam.Render(); GL.SetRevertBackfacing(false); //Refractionpass //TODO: If we want to use this as a refraction seen from under the seaplane, // the cameraclear should be skybox. offscreenCam.cullingMask = cullingMask; offscreenCam.targetTexture = refractionTexture; obliqueProjection = projection; offscreenCam.transform.position = renderCamera.transform.position; offscreenCam.transform.rotation = renderCamera.transform.rotation; offscreenCam.worldToCameraMatrix = originalWorldToCam; cameraSpaceClipPlane = CameraHelper.CameraSpacePlane(offscreenCam, Vector3.zero, Vector3.up, -1.0f); CameraHelper.CalculateObliqueMatrix(ref obliqueProjection, cameraSpaceClipPlane); offscreenCam.projectionMatrix = obliqueProjection; //if (!renderRefraction) //offscreenCam.cullingMask = 0; offscreenCam.Render(); offscreenCam.projectionMatrix = projection; offscreenCam.targetTexture = null; }
// This is called when it's known that the object will be rendered by some // camera. We render reflections and do other updates here. // Because the script executes in edit mode, reflections for the scene view // camera will just work! public void OnWillRenderObject() { var rend = GetComponent <Renderer>(); if (!enabled || !rend || !rend.sharedMaterial || !rend.enabled) { return; } Camera cam = Camera.current; if (!cam) { return; } // Safeguard from recursive reflections. if (s_InsideRendering) { return; } s_InsideRendering = true; // Camera reflectionCamera; CreateMirrorObjects(cam, out reflectionCamera); // find out the reflection plane: position and normal in world space Vector3 pos = transform.position; Vector3 normal = transform.up; UpdateCameraModes(cam, reflectionCamera); // Render reflection // 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; CameraHelper.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 = CameraHelper.CameraSpacePlane(reflectionCamera, pos, normal, 1.0f); //Matrix4x4 projection = cam.projectionMatrix; //Matrix4x4 projection = cam.CalculateObliqueMatrix(clipPlane); Matrix4x4 clipP = reflectionCamera.projectionMatrix; CameraHelper.CalculateObliqueMatrix(ref clipP, clipPlane); reflectionCamera.projectionMatrix = clipP; 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); reflectionCamera.Render(); //reflectionCamera.transform.position = oldpos; GL.SetRevertBackfacing(false); Material[] materials = rend.sharedMaterials; foreach (Material mat in materials) { if (mat.HasProperty("_ReflectionTex")) { mat.SetTexture("_ReflectionTex", m_ReflectionTexture); } } // Restore pixel light count s_InsideRendering = false; }