//Main method for individual reflection scripts not using recursion. public Camera ExecuteRenderSequence(ScriptableRenderContext src, Camera sentCamera = null, bool inverted = true, bool enableRender = true) { if (this != null) { var cameraToUse = sentCamera; if (cameraToUse == null && this.gameObject != null) { cameraToUse = _targetCamera; } //Avoid processing cameras used for reflection probes if (cameraToUse != null && cameraToUse.cameraType == CameraType.Reflection) { return(null); } //Frame skip checks bool skipFrame = _fpsCounter % planarLayerSettings.frameSkip != 0; if (skipFrame) { return(null); } //Resetting FPS skip counter to avoid storing large ints over long play sessions. if (_fpsCounter > 1000) { _fpsCounter = 0; } //Caching intial fog state, to reset after it is disabled for reflection (NOTE:this should be unnecessary now, will look at removing) var fogcache = RenderSettings.fog; RenderSettings.fog = false; //Create temporary render textures and camera entity CreateMirrorObjects(cameraToUse, out Camera reflectionCamera); //Sync current reflection settings to camera entity UpdateCameraModes(cameraToUse, reflectionCamera); //Apply culling mask layer options to camera entity reflectionCamera.cullingMask = planarLayerSettings.reflectLayers; //Determine the direction of the reflection from the user specified settings. float3 normal = planarLayerSettings.direction; //Job setup NativeArray <Matrix4x4> resultMatrix = new NativeArray <Matrix4x4>(1, Allocator.TempJob); CalculateReflectionMatrixJob calculateReflectionMatrix = new CalculateReflectionMatrixJob { reflectionMat = Matrix4x4.identity, plane = new float4(normal.x, normal.y, normal.z, -planarLayerSettings.clipPlaneOffset), resultMatrix = resultMatrix }; //Start reflection matrix calculation job JobHandle handle = calculateReflectionMatrix.Schedule(); //Setup camera clip plane calculation job with results of previous job NativeArray <float4> cameraSpacePlaneResult = new NativeArray <float4>(1, Allocator.TempJob); CameraSpacePlaneJob cameraSpacePlaneJob = new CameraSpacePlaneJob(); //Assign current user values cameraSpacePlaneJob.normal = normal; cameraSpacePlaneJob.resultMatrix = resultMatrix; cameraSpacePlaneJob.sideSign = inverted ? 1.0f : -1.0f; cameraSpacePlaneJob.offsetPos = normal * planarLayerSettings.clipPlaneOffset; if (cameraToUse != null) { cameraSpacePlaneJob.worldToCameraMatrix = cameraToUse.worldToCameraMatrix; cameraSpacePlaneJob.cameraSpacePlaneResult = cameraSpacePlaneResult; //Calculate clip plane job start JobHandle cameraSpaceHandle = cameraSpacePlaneJob.Schedule(handle); Matrix4x4 projectionMatrix = cameraToUse.projectionMatrix; NativeArray <Matrix4x4> matrixtemp = new NativeArray <Matrix4x4>(1, Allocator.TempJob); //Setup job for calculating oblique projection matrix MakeProjectionMatrixObliqueJob makeProjectionMatrixObliqueJob = new MakeProjectionMatrixObliqueJob(); makeProjectionMatrixObliqueJob.matrix = projectionMatrix; makeProjectionMatrixObliqueJob.matrixtemp = matrixtemp; makeProjectionMatrixObliqueJob.cameraSpacePlaneResult = cameraSpacePlaneResult; //Start oblique projection job JobHandle makeProjectionMatrixObliqueHandle = makeProjectionMatrixObliqueJob.Schedule(cameraSpaceHandle); makeProjectionMatrixObliqueHandle.Complete(); //Assign position from current used camera to entity camera reflectionCamera.transform.position = cameraToUse.transform.position; //Calculate entity cameras world to camera matrix by multiplying the main cameras world to camera matrix //by the results of the cameraSpacePlane job reflectionCamera.worldToCameraMatrix = cameraToUse.worldToCameraMatrix * resultMatrix[0]; cameraSpacePlaneJob.cameraSpacePlaneResult = cameraSpacePlaneResult; projectionMatrix = matrixtemp[0]; matrixtemp.Dispose(); //Assign oblique projection matric job result to entity camera projection matrix reflectionCamera.projectionMatrix = projectionMatrix; //Assign rotation from current used camera to entity camera reflectionCamera.transform.rotation = cameraToUse.transform.rotation; } //Cache culling settings(like the fog, I don't believe this should be needed anymore, will test though) var oldInvertCulling = GL.invertCulling; //Invert culling to show the backs of objects in reflections GL.invertCulling = inverted; //Assign already setup temporary rendertexture to entity camera reflectionCamera.targetTexture = _reflTexture; if (enableRender) {//Manually render frame with entity camera UniversalRenderPipeline.RenderSingleCamera(src, reflectionCamera); } //Restore cached culling GL.invertCulling = oldInvertCulling; if (enableRender) { //Update shader property method UpdateShader(); } //Restore fog RenderSettings.fog = fogcache; return(reflectionCamera); } else { return(null); } }
private Camera RenderTargetCamera(Camera sentCamera, bool invert = true, bool renderCam = true, ScriptableRenderContext src = new ScriptableRenderContext()) { var cameraToUse = sentCamera; if (cameraToUse == null && this.gameObject != null) { cameraToUse = thisCamera; } if (cameraToUse.cameraType == CameraType.Reflection) { return(null); } _skipFrame = _fpsCounter % planarLayerSettings.frameSkip != 0; if (_skipFrame) { return(null); } if (_processingRenderCamera) { return(null); } _processingRenderCamera = true; var fogcache = RenderSettings.fog; RenderSettings.fog = false; CreateMirrorObjects(cameraToUse, out Camera reflectionCamera); UpdateCameraModes(cameraToUse, reflectionCamera); reflectionCamera.cullingMask = planarLayerSettings.reflectLayers; float3 normal = planarLayerSettings.direction; float d = -planarLayerSettings.clipPlaneOffset; float4 reflectionPlane = new float4(normal.x, normal.y, normal.z, d); Matrix4x4 reflection = Matrix4x4.identity; NativeArray <Matrix4x4> resultMatrix = new NativeArray <Matrix4x4>(1, Allocator.TempJob); CalculateReflectionMatrixJob calculateReflectionMatrix = new CalculateReflectionMatrixJob { reflectionMat = reflection, plane = reflectionPlane, ResultMatrix = resultMatrix }; JobHandle handle = calculateReflectionMatrix.Schedule(); NativeArray <float4> cameraSpacePlaneResult = new NativeArray <float4>(1, Allocator.TempJob); CameraSpacePlaneJob cameraSpacePlaneJob = new CameraSpacePlaneJob(); cameraSpacePlaneJob.Normal = normal; cameraSpacePlaneJob.ResultMatrix = resultMatrix; cameraSpacePlaneJob.SideSign = invert ? 1.0f : -1.0f; cameraSpacePlaneJob.OffsetPos = normal * planarLayerSettings.clipPlaneOffset; cameraSpacePlaneJob.WorldToCameraMatrix = cameraToUse.worldToCameraMatrix; cameraSpacePlaneJob.CameraSpacePlaneResult = cameraSpacePlaneResult; JobHandle cameraSpaceHandle = cameraSpacePlaneJob.Schedule(handle); // cameraSpaceHandle.Complete(); Matrix4x4 projectionMatrix = cameraToUse.projectionMatrix; // cameraSpacePlaneResult.Dispose(); // if (reflectionCamera.orthographic) // projectionMatrix = cameraToUse.CalculateObliqueMatrix(clipPlane); // else // { NativeArray <Matrix4x4> matrixtemp = new NativeArray <Matrix4x4>(1, Allocator.TempJob); MakeProjectionMatrixObliqueJob makeProjectionMatrixObliqueJob = new MakeProjectionMatrixObliqueJob(); makeProjectionMatrixObliqueJob.Matrix = projectionMatrix; makeProjectionMatrixObliqueJob.Matrixtemp = matrixtemp; makeProjectionMatrixObliqueJob.cameraSpacePlaneResult = cameraSpacePlaneResult; JobHandle makeProjectionMatrixObliqueHandle = makeProjectionMatrixObliqueJob.Schedule(cameraSpaceHandle); makeProjectionMatrixObliqueHandle.Complete(); Matrix4x4 worldToCameraMatrix = cameraToUse.worldToCameraMatrix * resultMatrix[0]; reflectionCamera.transform.position = cameraToUse.transform.position; reflectionCamera.worldToCameraMatrix = worldToCameraMatrix; cameraSpacePlaneJob.CameraSpacePlaneResult = cameraSpacePlaneResult; projectionMatrix = matrixtemp[0]; matrixtemp.Dispose(); // } reflectionCamera.projectionMatrix = projectionMatrix; reflectionCamera.transform.rotation = cameraToUse.transform.rotation; var oldInvertCulling = GL.invertCulling; GL.invertCulling = invert; reflectionCamera.targetTexture = _reflTexture; if (renderCam) { UniversalRenderPipeline.RenderSingleCamera(src, reflectionCamera); } GL.invertCulling = oldInvertCulling; if (renderCam) { UpdateMaterialProperties(cameraToUse); } RenderSettings.fog = fogcache; _processingRenderCamera = false; return(reflectionCamera); }