/// <summary> /// Renders the reflection and refraction of ocean. /// </summary> private void RenderReflectionAndRefraction() { if (Camera.current == offscreenCamera) { return; } if (reflectionTexture == null || refractionTexture == null) { return; } if (mainCameraTransform == null) { mainCameraTransform = Camera.main.transform; } Camera mainCamera = Camera.mainCamera; Matrix4x4 originalWorldToCamera = mainCamera.worldToCameraMatrix; int cullingMask = ~(1 << 4) & renderLayers.value; // Reflection pass. float y = -transform.position.y; Matrix4x4 reflectionMatrix = Matrix4x4.zero; CameraUtility.CalculateReflectionMatrix(ref reflectionMatrix, new Vector4(0.0f, 1.0f, 0.0f, y)); offscreenCamera.backgroundColor = RenderSettings.fogColor; offscreenCameraTransform.position = reflectionMatrix.MultiplyPoint(mainCameraTransform.position); offscreenCameraTransform.rotation = mainCameraTransform.rotation; offscreenCamera.worldToCameraMatrix = originalWorldToCamera * reflectionMatrix; offscreenCamera.cullingMask = cullingMask; offscreenCamera.targetTexture = reflectionTexture; // Need to reverse face culling for reflection pass, since the camera is now flipped upside/downside. GL.SetRevertBackfacing(true); Vector4 cameraSpaceClipPlane = CameraUtility.CameraSpaceClipPlane(offscreenCamera, new Vector3(0.0f, transform.position.y, 0.0f), Vector3.up, 1.0f); Matrix4x4 projection = mainCamera.projectionMatrix; Matrix4x4 obliqueProjection = projection; offscreenCamera.fieldOfView = mainCamera.fieldOfView; offscreenCamera.aspect = mainCamera.aspect; CameraUtility.CalculateObliqueMatrix(ref obliqueProjection, cameraSpaceClipPlane); // Do the actual render, with the near plane set as the clipping plane. See the pro water source for details. offscreenCamera.projectionMatrix = obliqueProjection; if (!reflectionEnabled) { offscreenCamera.cullingMask = 0; } offscreenCamera.Render(); GL.SetRevertBackfacing(false); // Refraction pass. offscreenCamera.cullingMask = cullingMask; offscreenCamera.targetTexture = refractionTexture; obliqueProjection = projection; offscreenCameraTransform.position = mainCameraTransform.position; offscreenCameraTransform.rotation = mainCameraTransform.rotation; offscreenCamera.worldToCameraMatrix = originalWorldToCamera; cameraSpaceClipPlane = CameraUtility.CameraSpaceClipPlane(offscreenCamera, Vector3.zero, Vector3.up, -1.0f); CameraUtility.CalculateObliqueMatrix(ref obliqueProjection, cameraSpaceClipPlane); offscreenCamera.projectionMatrix = obliqueProjection; offscreenCamera.Render(); offscreenCamera.projectionMatrix = projection; offscreenCamera.targetTexture = null; }