예제 #1
0
 //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);
    }