private void OnBeginCameraRenderingSRP(ScriptableRenderContext context, Camera cam) { ValidateMaterial(); SubmitRenderList(cam); if (Profile == null) { return; } if (cam.cameraType != CameraType.Game && cam.cameraType != CameraType.SceneView) { return; } if (cam.name.EndsWith("Preview Camera")) { return; } if (ReflCameras.ContainsValue(cam)) { //cam is a reflection camera return; } else { if (Profile.EnableReflection) { RenderReflectionTextureSRP(context, cam); } if (Profile.EnableRefraction) { //RenderRefractionTextureSRP(context, cam); } } }
private RenderTexture GetReflectionRt(Camera cam) { if (!ReflRenderTextures.ContainsKey(cam)) { ReflRenderTextures.Add(cam, null); } int resolution = 128; if (Profile != null) { resolution = Profile.ReflectionTextureResolution; } RenderTexture rt = ReflRenderTextures[cam]; if (rt == null) { rt = new RenderTexture(resolution, resolution, 16, RenderTextureFormat.ARGB32); } if (rt.width != resolution || rt.height != resolution) { Camera reflCam; if (ReflCameras.TryGetValue(cam, out reflCam)) { reflCam.targetTexture = null; } rt.Release(); PUtilities.DestroyObject(rt); rt = new RenderTexture(resolution, resolution, 16, RenderTextureFormat.ARGB32); } rt.name = string.Format("~ReflectionRt_{0}_{1}", cam.name, resolution); ReflRenderTextures[cam] = rt; if (cam.stereoEnabled) { rt.Release(); } return(rt); }
private void OnWillRenderObject() { if (PCommon.CurrentRenderPipeline == PRenderPipelineType.Universal) { return; } if (Profile == null) { return; } Camera currentCam = Camera.current; if (currentCam == null) { return; } if (currentCam.cameraType != CameraType.Game && currentCam.cameraType != CameraType.SceneView) { return; } if (currentCam.name.EndsWith("Preview Camera")) { return; } if (ReflCameras.ContainsValue(currentCam)) { return; } if (Profile.EnableReflection) { RenderReflectionTexture(currentCam); } }
private void RenderReflectionTexture(Camera cam) { if (MeshType == PWaterMeshType.Spline) { return; } bool isBackface = cam.transform.position.y < transform.position.y; if (isBackface) { return; } if (cam.stereoEnabled) { return; } //prepare reflection camera if (!ReflCameras.ContainsKey(cam)) { ReflCameras.Add(cam, null); } if (ReflCameras[cam] == null) { GameObject g = new GameObject(); g.name = "~ReflectionCamera_" + cam.name; g.hideFlags = HideFlags.HideAndDontSave; Camera rCam = g.AddComponent <Camera>(); rCam.enabled = false; g.AddComponent <Skybox>(); g.AddComponent <FlareLayer>(); PUtilities.ResetTransform(g.transform, transform); ReflCameras[cam] = rCam; } //define reflection plane by position & normal in world space Vector3 planePos = transform.position; Vector3 planeNormal = Vector3.up; //disable pixel light if needed int oldPixelLightCount = QualitySettings.pixelLightCount; if (!Profile.EnableReflectionPixelLight) { QualitySettings.pixelLightCount = 0; } //set up camera and render Camera reflectionCamera = ReflCameras[cam]; reflectionCamera.enabled = false; reflectionCamera.targetTexture = GetReflectionRt(cam); MatchCameraSettings(cam, reflectionCamera); // Reflect camera around reflection plane float d = -Vector3.Dot(planeNormal, planePos) - Profile.ReflectionClipPlaneOffset; Vector4 reflectionPlane = new Vector4(planeNormal.x, planeNormal.y, planeNormal.z, d); Matrix4x4 reflection = CalculateReflectionMatrix(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. bool isBackFace = cam.transform.position.y < transform.position.y; Vector4 clipPlane = CameraSpacePlane(reflectionCamera, planePos, planeNormal, Profile.ReflectionClipPlaneOffset, isBackFace ? -1.0f : 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) & Profile.ReflectionLayers.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; //restore pixel light if (!Profile.EnableReflectionPixelLight) { QualitySettings.pixelLightCount = oldPixelLightCount; } }
private void RenderReflectionTextureSRP(ScriptableRenderContext context, Camera cam) { if (MeshType == PWaterMeshType.Spline) { return; } bool isBackface = cam.transform.position.y < transform.position.y; if (isBackface) { return; } if (cam.stereoEnabled) { return; } //prepare reflection camera if (!ReflCameras.ContainsKey(cam)) { ReflCameras.Add(cam, null); } if (ReflCameras[cam] == null) { GameObject g = new GameObject(); g.name = "~ReflectionCamera_" + cam.name; //g.hideFlags = HideFlags.HideAndDontSave; Camera rCam = g.AddComponent <Camera>(); rCam.enabled = false; g.AddComponent <Skybox>(); g.AddComponent <FlareLayer>(); ////TODO: Remove on release //if (cam.cameraType == CameraType.Game) //{ // PCameraFrustumVisualizer vis = g.AddComponent<PCameraFrustumVisualizer>(); ; // vis.drawGizmos = true; // vis.leftEye = true; // vis.rightEye = true; // vis.monoEye = true; // vis.alpha = 0.2f; // vis.cam = rCam; //} PUtilities.ResetTransform(g.transform, transform); ReflCameras[cam] = rCam; } //define reflection plane by position & normal in world space Vector3 planePos = transform.position; Vector3 planeNormal = transform.up; int lastPixelLightCount = QualitySettings.pixelLightCount; if (!Profile.EnableReflectionPixelLight) { QualitySettings.pixelLightCount = 0; } bool lastInvertCulling = GL.invertCulling; GL.invertCulling = !lastInvertCulling; //set up camera and render Camera reflectionCamera = ReflCameras[cam]; reflectionCamera.enabled = false; reflectionCamera.targetTexture = GetReflectionRt(cam); MatchCameraSettings(cam, reflectionCamera); // Reflect camera around reflection plane float d = -Vector3.Dot(planeNormal, planePos) - Profile.ReflectionClipPlaneOffset; Vector4 reflectionPlane = new Vector4(planeNormal.x, planeNormal.y, planeNormal.z, d); Matrix4x4 reflection = CalculateReflectionMatrix(reflectionPlane, Camera.MonoOrStereoscopicEye.Mono); 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. bool isBackFace = cam.transform.position.y < transform.position.y; Vector4 clipPlane = CameraSpacePlane(reflectionCamera, planePos, planeNormal, Profile.ReflectionClipPlaneOffset, isBackFace && ShouldRenderBackface ? -1.0f : 1.0f); Matrix4x4 obliqueMatrix = cam.CalculateObliqueMatrix(clipPlane); reflectionCamera.projectionMatrix = obliqueMatrix; // Set custom culling matrix from the current camera reflectionCamera.cullingMatrix = cam.projectionMatrix * cam.worldToCameraMatrix; reflectionCamera.cullingMask = ~(1 << 4) & Profile.ReflectionLayers.value; // never render water layer reflectionCamera.transform.position = newpos; Vector3 euler = cam.transform.eulerAngles; reflectionCamera.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z); UniversalRenderPipeline.RenderSingleCamera(context, reflectionCamera); QualitySettings.pixelLightCount = lastPixelLightCount; GL.invertCulling = lastInvertCulling; }