Beispiel #1
0
        /// <summary>
        /// Executes the planar reflections functions
        /// </summary>
        /// <param name="context"></param>
        /// <param name="cam"></param>
        public void ExecutePlanarReflections(ScriptableRenderContext context, Camera cam)
        {
            if (m_settings.m_disableSkyboxReflections)
            {
                return;
            }

            if (cam.cameraType == CameraType.Reflection || cam.cameraType == CameraType.Preview)
            {
                return;
            }

            UpdateReflectionCamera(cam);
            PlanarReflectionTexture();

            if (m_reflectionData == null)
            {
                m_reflectionData = new PlanarReflectionSettingData();
            }

            m_reflectionData.Get();
            m_reflectionData.Set();
            BeginPlanarReflections?.Invoke(context, m_reflectionCamera);
#if UPPipeline
            UniversalRenderPipeline.RenderSingleCamera(context, m_reflectionCamera);
#endif
            PWS_WaterSystem.Instance.SetReflectionTexture(m_reflectionTexture);
            m_reflectionData.Restore();
        }
        void InitializeLightConstants(NativeArray <VisibleLight> lights, int lightIndex, out Vector4 lightPos, out Vector4 lightColor, out Vector4 lightAttenuation, out Vector4 lightSpotDir, out Vector4 lightOcclusionProbeChannel)
        {
            UniversalRenderPipeline.InitializeLightConstants_Common(lights, lightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir, out lightOcclusionProbeChannel);

            // When no lights are visible, main light will be set to -1.
            // In this case we initialize it to default values and return
            if (lightIndex < 0)
            {
                return;
            }

            VisibleLight lightData = lights[lightIndex];
            Light        light     = lightData.light;

            if (light == null)
            {
                return;
            }

            if (light.bakingOutput.lightmapBakeType == LightmapBakeType.Mixed &&
                lightData.light.shadows != LightShadows.None &&
                m_MixedLightingSetup == MixedLightingSetup.None)
            {
                switch (light.bakingOutput.mixedLightingMode)
                {
                case MixedLightingMode.Subtractive:
                    m_MixedLightingSetup = MixedLightingSetup.Subtractive;
                    break;

                case MixedLightingMode.Shadowmask:
                    m_MixedLightingSetup = MixedLightingSetup.ShadowMask;
                    break;
                }
            }
        }
Beispiel #3
0
        private void DoPlanarReflections(ScriptableRenderContext context, Camera camera)
        {
            /* If reference position and proxy position is exactly the same, we end up in some degeneracies triggered
             * by engine code when computing culling parameters. This is an extremely rare case, but can happen
             * in editor when focusing on the planar probe. So if that happens, we offset them 0.1 mm apart.
             * if(Vector3.Distance(result.proxyPosition, referencePosition) < 1e-4f)
             * {
             *    referencePosition += new Vector3(1e-4f, 1e-4f, 1e-4f);
             * }*/

            if (camera.cameraType == CameraType.Reflection || camera.cameraType == CameraType.Preview)
            {
                return;
            }
            if (!reflectionTarget)
            {
                return;
            }

            UpdateReflectionCamera(camera);
            CreateReflectionTexture(camera);

            var data = new PlanarReflectionSettingData();

            data.Set();
            BeginPlanarReflections?.Invoke(context, _reflectionCamera);
            if (_reflectionCamera.WorldToViewportPoint(reflectionTarget.transform.position).z < 100000)
            {
                UniversalRenderPipeline.RenderSingleCamera(context, _reflectionCamera);
            }
            data.Restore();
            Shader.SetGlobalTexture(_planarReflectionTextureId, _reflectionTexture);
        }
Beispiel #4
0
        private void ExecutePlanarReflections(ScriptableRenderContext context, Camera camera)
        {
            if (!enableReflections)
            {
                Cleanup();
                return;
            }
            if (camera.cameraType == CameraType.Reflection || camera.cameraType == CameraType.Preview || material == null || material.shader.name == "Shader Graphs/Stylized Water For URP Mobile")
            {
                return;
            }

            UpdateReflectionCamera(camera);
            ReflectionTexture(camera);

            var data = new PlanarReflectionSettingData();

            data.Set();

            BeginPlanarReflections?.Invoke(context, _reflectionCamera);
            UniversalRenderPipeline.RenderSingleCamera(context, _reflectionCamera);

            data.Restore();
            Shader.SetGlobalTexture(_planarReflectionTextureId, _reflectionTexture);
        }
Beispiel #5
0
    void RecursiveRenderPortal(Portal inPortal, Portal outPortal, ScriptableRenderContext context)
    {
        Transform prev = portalCamera.transform;

        prev.SetPositionAndRotation(player.position, player.rotation);

        Vector3[]    pos = new Vector3[iterations];
        Quaternion[] rot = new Quaternion[iterations];

        for (int i = iterations - 1; i >= 0; i--)
        {
            prev   = RenderPortal(inPortal, outPortal, prev);
            pos[i] = prev.position;
            rot[i] = prev.rotation;
        }
        for (int i = 0; i < iterations; i++)
        {
            float dist = Vector3.Magnitude(pos[i] - outPortal.transform.position);
            portalCamera.transform.SetPositionAndRotation(pos[i], rot[i]);

            Vector4 clipPlane = CalculateClipPlane(portalCamera, outPortal.transform);
            portalCamera.projectionMatrix = mainCamera.CalculateObliqueMatrix(clipPlane);
            // portalCamera.Render();
            UniversalRenderPipeline.RenderSingleCamera(context, portalCamera);
        }
    }
Beispiel #6
0
    private void RenderCamera(Portal inPortal, Portal outPortal, int iterationID, ScriptableRenderContext SRC)
    {
        Transform inTransform  = inPortal.transform;
        Transform outTransform = outPortal.transform;

        Transform cameraTransform = portalCamera.transform;

        cameraTransform.position = transform.position;
        cameraTransform.rotation = transform.rotation;

        for (int i = 0; i <= iterationID; ++i)
        {
            Vector3 relativePos = inTransform.InverseTransformPoint(cameraTransform.position);
            relativePos = Quaternion.Euler(0.0f, 180.0f, 0.0f) * relativePos;
            cameraTransform.position = outTransform.TransformPoint(relativePos);


            Quaternion relativeRot = Quaternion.Inverse(inTransform.rotation) * cameraTransform.rotation;
            relativeRot = Quaternion.Euler(0.0f, 180.0f, 0.0f) * relativeRot;
            cameraTransform.rotation = outTransform.rotation * relativeRot;
        }

        Plane   p = new Plane(-outTransform.forward, outTransform.position);
        Vector4 clipPlaneWorldSpace  = new Vector4(p.normal.x, p.normal.y, p.normal.z, p.distance);
        Vector4 clipPlaneCameraSpace =
            Matrix4x4.Transpose(Matrix4x4.Inverse(portalCamera.worldToCameraMatrix)) * clipPlaneWorldSpace;

        var newMatrix = mainCamera.CalculateObliqueMatrix(clipPlaneCameraSpace);

        portalCamera.projectionMatrix = newMatrix;

        UniversalRenderPipeline.RenderSingleCamera(SRC, portalCamera);
    }
        private void ProcessPlanarReflection(ScriptableRenderContext context, Camera camera)
        {
            // we dont want to render planar reflections in reflections or previews
            if (camera.cameraType == CameraType.Reflection || camera.cameraType == CameraType.Preview)
            {
                return;
            }
            SetupReflectionTexture(camera);
            UpdateReflectionCamera(camera);

            //render plane reflection render setting...
            GL.invertCulling = true;
            bool  originalFogSetate   = RenderSettings.fog;
            int   originalMaxLODLevel = QualitySettings.maximumLODLevel;
            float originalLODBias     = QualitySettings.lodBias;

            RenderSettings.fog = false; // disable fog for now as it's incorrect with projection
            QualitySettings.maximumLODLevel = 1;
            QualitySettings.lodBias         = originalLODBias * 0.5f;

            //觸發一個plane reflection的事件…外面需要知道嗎?…
            //BeginPlanarReflections?.Invoke(context, _reflectionCamera); // callback Action for PlanarReflection
            UniversalRenderPipeline.RenderSingleCamera(context, m_reflectionCamera); // render planar reflections

            //restore original render setting...
            GL.invertCulling   = false;
            RenderSettings.fog = originalFogSetate;
            QualitySettings.maximumLODLevel = originalMaxLODLevel;
            QualitySettings.lodBias         = originalLODBias;

            // Assign texture to water shader
            Shader.SetGlobalTexture(m_planarReflectionTextureId, m_reflectionRT);
        }
Beispiel #8
0
            /// <summary>
            /// Recursivelly renders the Node and it's children in a depth first order.
            /// </summary>
            /// <param name="ctx">The rendering context.</param>
            /// <param name="temporaryPoolItem">An render texture to be released after render.</param>
            /// <param name="originalTexture">The previous texture attached to this Node's Portal.</param>
            internal void Render(ScriptableRenderContext ctx, out RenderTexturePool.Item temporaryPoolItem, out Texture originalTexture)
            {
                var visiblePortalResourcesList = new List <VisiblePortalResources>();

                foreach (var node in this.dependencies)
                {
                    node.Render(ctx, out var visiblePortalTempPoolItem, out var visiblePortalOriginalTexture);
                    visiblePortalResourcesList.Add(new VisiblePortalResources
                    {
                        visiblePortal   = node.portal,
                        poolItem        = visiblePortalTempPoolItem,
                        originalTexture = visiblePortalOriginalTexture
                    });
                }

                temporaryPoolItem = renderer.RenderTexturePool.GetRenderTexture();
                this.renderer.PortalCamera.targetTexture = temporaryPoolItem.renderTexture;

                this.renderer.PortalCamera.transform.SetPositionAndRotation(this.viewPose.GetColumn(3), this.viewPose.rotation);

                Matrix4x4 cameraTransform = Matrix4x4.Transpose(Matrix4x4.Inverse(this.renderer.PortalCamera.worldToCameraMatrix));
                Vector4   clippingPlane   = this.portal.Destination.GetClippingPlane();

                this.renderer.PortalCamera.projectionMatrix = this.renderer.BaseCamera.CalculateObliqueMatrix(cameraTransform * clippingPlane);

                if (this.depth > this.renderer.MaxRecursionDepth)
                {
                    RenderTexture.active = temporaryPoolItem.renderTexture;
                    GL.ClearWithSkybox(true, this.renderer.PortalCamera);
                }
                else
                {
                    this.portal.Destination.DisableScreen();
                    UniversalRenderPipeline.RenderSingleCamera(ctx, this.renderer.PortalCamera);
                    this.portal.Destination.EnableScreen();
                }


                foreach (var resources in visiblePortalResourcesList)
                {
                    resources.visiblePortal.SetTexture(resources.originalTexture);

                    if (resources.poolItem != null)
                    {
                        this.renderer.RenderTexturePool.ReleaseRenderTexture(resources.poolItem);
                    }
                }

                originalTexture = this.portal.GetTexture();
                this.portal.SetTexture(temporaryPoolItem.renderTexture);
            }
Beispiel #9
0
    // 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 BeginCameraRender(ScriptableRenderContext context, Camera cam)
    {
        if (!enabled || !m_renderer || !m_renderer.sharedMaterial || !m_renderer.enabled)
        {
            return;
        }

        //Camera cam = Camera.current;
        //if (!cam)
        //    return;

        // Safeguard from recursive reflections.
        if (s_InsideRendering)
        {
            return;
        }

        s_InsideRendering = true;

        Camera ripplesCamera;

        CreateRippleObjects(cam, out ripplesCamera);

        // find out the reflection plane: position and normal in world space
        Vector3 pos    = transform.position;
        Vector3 normal = transform.up;

        UpdateCameraModes(cam, ripplesCamera);

        ripplesCamera.worldToCameraMatrix = cam.worldToCameraMatrix;

        ripplesCamera.projectionMatrix = cam.projectionMatrix;

        ripplesCamera.targetTexture      = m_ripplesTexture;
        ripplesCamera.transform.position = cam.transform.position;
        ripplesCamera.transform.rotation = cam.transform.rotation;
        ripplesCamera.ResetWorldToCameraMatrix();
        UniversalRenderPipeline.RenderSingleCamera(context, ripplesCamera);
        Material[] materials = m_renderer.sharedMaterials;
        foreach (Material mat in materials)
        {
            if (mat.HasProperty("_HeightTex"))
            {
                mat.SetTexture("_HeightTex", m_ripplesTexture);
            }
        }

        s_InsideRendering = false;
    }
Beispiel #10
0
        public void ExecutePlanarReflections(
            ScriptableRenderContext context,
            Camera camera)
        {
            if (camera.cameraType == CameraType.Reflection)
            {
                return;
            }

            if (camera.cameraType == CameraType.Game && camera != Camera.main)
            {
                return;
            }

            GL.invertCulling   = true;
            RenderSettings.fog = false;
            var max  = QualitySettings.maximumLODLevel;
            var bias = QualitySettings.lodBias;

            QualitySettings.maximumLODLevel = 0;
            QualitySettings.lodBias         = bias / 2f;

            UpdateReflectionCamera(camera);
            m_ReflectionCamera.cameraType = camera.cameraType;

            var res = ReflectionResolution(camera, UniversalRenderPipeline.asset.renderScale);

            if (m_ReflectionTexture == null || res.x != m_ReflectionTexture.width || res.y != m_ReflectionTexture.height)
            {
                RenderTexture.ReleaseTemporary(m_ReflectionTexture);

                bool useHDR10 = camera.allowHDR;// SystemInfo.SupportsRenderTextureFormat(RenderTextureFormat.RGB111110Float);
                RenderTextureFormat hdrFormat =
                    useHDR10 ? RenderTextureFormat.RGB111110Float : RenderTextureFormat.DefaultHDR;
                m_ReflectionTexture = RenderTexture.GetTemporary(res.x, res.y, 16,
                                                                 GraphicsFormatUtility.GetGraphicsFormat(hdrFormat, true));
            }

            m_ReflectionCamera.targetTexture = m_ReflectionTexture;

            UniversalRenderPipeline.RenderSingleCamera(context, m_ReflectionCamera);

            GL.invertCulling   = false;
            RenderSettings.fog = true;
            QualitySettings.maximumLODLevel = 0;
            QualitySettings.lodBias         = bias;
            Shader.SetGlobalTexture(planarReflectionTextureID, m_ReflectionTexture);
        }
        static bool CreateLightValidation()
        {
            UniversalRenderPipeline pipeline = UnityEngine.Rendering.RenderPipelineManager.currentPipeline as UniversalRenderPipeline;

            if (pipeline != null)
            {
                UniversalRenderPipelineAsset asset = UniversalRenderPipeline.asset;
                Renderer2DData assetData           = asset.scriptableRendererData as Renderer2DData;
                if (assetData != null)
                {
                    return(true);
                }
            }

            return(false);
        }
Beispiel #12
0
        /// <summary>
        /// Renders the view on the other side of the portal from the perspective of a given <see cref="Camera"/>.
        /// </summary>
        /// <param name="frameCamera">The <see cref="Camera"/> that is rendering the frame.</param>
        public void RenderPortal(ScriptableRenderContext context, Camera frameCamera)
        {
            bool onFrontSide = transform.InverseTransformPoint(frameCamera.transform.position).y >= 0;

            // maincam_world -> get local to thisportal -> transform to local to otherportal (but all of this is backwards bc matrices) (not flipping bc convenicence of normals)
            Matrix4x4 transformMatrix = otherPortal.transform.localToWorldMatrix * transform.worldToLocalMatrix * frameCamera.transform.localToWorldMatrix;

            renderCamera.transform.SetPositionAndRotation(transformMatrix.GetPosition(), transformMatrix.rotation);
            renderCamera.transform.RotateAround(otherPortal.transform.position, otherPortal.transform.forward, 180);

            // up instead of forward bc I'm dumb
            Vector3 otherPortalNormal    = otherPortal.transform.up * (onFrontSide ? 1 : -1);
            Plane   clipPlanePlane       = new Plane(otherPortalNormal, otherPortal.transform.position - otherPortalNormal * 0.01f);
            Vector4 clipPlane            = new Vector4(clipPlanePlane.normal.x, clipPlanePlane.normal.y, clipPlanePlane.normal.z, clipPlanePlane.distance);
            Vector4 clipPlaneCameraSpace = Matrix4x4.Transpose(Matrix4x4.Inverse(renderCamera.worldToCameraMatrix)) * clipPlane;

            renderCamera.projectionMatrix = frameCamera.CalculateObliqueMatrix(clipPlaneCameraSpace);

            otherPortal.meshRenderer.enabled = false;
            UniversalRenderPipeline.RenderSingleCamera(context, renderCamera);
            otherPortal.meshRenderer.enabled = true;
        }
Beispiel #13
0
    private void RenderReflections(ScriptableRenderContext context, Camera camera)
    {
        if (camera.cameraType == CameraType.Reflection || camera.cameraType == CameraType.Preview)
        {
            return;
        }

        currentFrame++;
        if (currentFrame % GetSkipFrameValue() != 0)
        {
            return;
        }

        UpdateReflectionCamera(camera);
        CreatePlanarReflectionTexture(camera);

        //remember current quality settings
        fogBeforeReflections     = RenderSettings.fog;
        maxLodBeforeReflections  = QualitySettings.maximumLODLevel;
        lodBiasBeforeReflections = QualitySettings.lodBias;

        //change quality settings to lower
        GL.invertCulling   = true;
        RenderSettings.fog = false;
        QualitySettings.maximumLODLevel = 1;
        QualitySettings.lodBias         = lodBiasBeforeReflections * 0.5f;

        //render
        UniversalRenderPipeline.RenderSingleCamera(context, reflectionCamera);

        //restore quality settings
        GL.invertCulling   = false;
        RenderSettings.fog = fogBeforeReflections;
        QualitySettings.maximumLODLevel = maxLodBeforeReflections;
        QualitySettings.lodBias         = lodBiasBeforeReflections;

        //make reflection texture global and accessible in every shader
        Shader.SetGlobalTexture(reflectionTextureId, reflectionTexture);
    }
    // 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 BeginCameraRender(ScriptableRenderContext context, Camera cam)
    {
        if (!enabled || !m_renderer || !m_renderer.sharedMaterial || !m_renderer.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);

        CalculateReflectionMatrix(out var 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  = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f);
        Matrix4x4 projection = cam.projectionMatrix;

        CalculateObliqueMatrix(ref projection, clipPlane);
        reflectionCamera.projectionMatrix = projection;

        reflectionCamera.targetTexture      = m_ReflectionTexture;
        reflectionCamera.transform.position = newpos;
        reflectionCamera.transform.rotation = Quaternion.LookRotation(reflection.MultiplyVector(cam.transform.forward), reflection.MultiplyVector(cam.transform.up));
        reflectionCamera.ResetWorldToCameraMatrix();
        UniversalRenderPipeline.RenderSingleCamera(context, reflectionCamera);
        reflectionCamera.transform.position = oldpos;
        Material[] materials = m_renderer.sharedMaterials;
        foreach (Material mat in materials)
        {
            if (mat.HasProperty("_ReflectionTex"))
            {
                mat.SetTexture("_ReflectionTex", m_ReflectionTexture);
            }
        }

        // Set matrix on the shader that transforms UVs from object space into screen
        // space. We want to just project reflection texture on screen.
        Matrix4x4 scaleOffset = Matrix4x4.TRS(
            new Vector3(0.5f, 0.5f, 0.5f), Quaternion.identity, new Vector3(0.5f, 0.5f, 0.5f));
        Vector3   scale = transform.lossyScale;
        Matrix4x4 mtx   = transform.localToWorldMatrix * Matrix4x4.Scale(new Vector3(1.0f / scale.x, 1.0f / scale.y, 1.0f / scale.z));

        mtx = scaleOffset * cam.projectionMatrix * cam.worldToCameraMatrix * mtx;
        foreach (Material mat in materials)
        {
            mat.SetMatrix("_RefProjMatrix", mtx);
        }

        s_InsideRendering = false;
    }
    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);
    }
Beispiel #16
0
    void RenderObject(ScriptableRenderContext context, Camera cam)
    {
        if (isRendering)
        {
            return;
        }
        if (ShaderLevel.CurrentLevel != ShaderLevel.Level.High)
        {
            return;
        }

        isRendering = true;
        position    = transform.position;
        normal      = transform.up;

        SetTextureSize(textureSize);

        reflectionCamera.clearFlags      = CameraClearFlags.SolidColor;
        reflectionCamera.backgroundColor = Color.clear;

        reflectionCamera.farClipPlane     = cam.farClipPlane;
        reflectionCamera.nearClipPlane    = cam.nearClipPlane;
        reflectionCamera.orthographic     = cam.orthographic;
        reflectionCamera.fieldOfView      = cam.fieldOfView;
        reflectionCamera.aspect           = cam.aspect;
        reflectionCamera.orthographicSize = cam.orthographicSize;
        reflectionCamera.cullingMask      = ~(1 << 4) & LayersToReflect.value;

        reflectionPlane = new Vector4(normal.x, normal.y, normal.z, -Vector3.Dot(normal, position) - Offset);

        reflectionMatrix.m00 = (1F - 2F * reflectionPlane[0] * reflectionPlane[0]);
        reflectionMatrix.m01 = (-2F * reflectionPlane[0] * reflectionPlane[1]);
        reflectionMatrix.m02 = (-2F * reflectionPlane[0] * reflectionPlane[2]);
        reflectionMatrix.m03 = (-2F * reflectionPlane[3] * reflectionPlane[0]);
        reflectionMatrix.m10 = (-2F * reflectionPlane[1] * reflectionPlane[0]);
        reflectionMatrix.m11 = (1F - 2F * reflectionPlane[1] * reflectionPlane[1]);
        reflectionMatrix.m12 = (-2F * reflectionPlane[1] * reflectionPlane[2]);
        reflectionMatrix.m13 = (-2F * reflectionPlane[3] * reflectionPlane[1]);
        reflectionMatrix.m20 = (-2F * reflectionPlane[2] * reflectionPlane[0]);
        reflectionMatrix.m21 = (-2F * reflectionPlane[2] * reflectionPlane[1]);
        reflectionMatrix.m22 = (1F - 2F * reflectionPlane[2] * reflectionPlane[2]);
        reflectionMatrix.m23 = (-2F * reflectionPlane[3] * reflectionPlane[2]);
        reflectionMatrix.m30 = 0F;
        reflectionMatrix.m31 = 0F;
        reflectionMatrix.m32 = 0F;
        reflectionMatrix.m33 = 1F;

        oldPosition = cam.transform.position;
        reflectionCamera.worldToCameraMatrix = cam.worldToCameraMatrix * reflectionMatrix;

        worldToCameraMatrix = reflectionCamera.worldToCameraMatrix;
        clipNormal          = worldToCameraMatrix.MultiplyVector(normal).normalized;
        clipPlane           = new Vector4(clipNormal.x, clipNormal.y, clipNormal.z, -Vector3.Dot(worldToCameraMatrix.MultiplyPoint(position + normal * Offset), clipNormal));

        projection     = cam.projectionMatrix;
        oblique        = clipPlane * (2.0F / (Vector4.Dot(clipPlane, projection.inverse * new Vector4(sgn(clipPlane.x), sgn(clipPlane.y), 1.0f, 1.0f))));
        projection[2]  = oblique.x - projection[3];
        projection[6]  = oblique.y - projection[7];
        projection[10] = oblique.z - projection[11];
        projection[14] = oblique.w - projection[15];
        reflectionCamera.projectionMatrix = projection;
        reflectionCamera.targetTexture    = reflectionTexture;

        GL.invertCulling = true;
        reflectionCamera.transform.position = reflectionMatrix.MultiplyPoint(oldPosition);
        eulerAngles = cam.transform.eulerAngles;
        reflectionCamera.transform.eulerAngles = new Vector3(0, eulerAngles.y, eulerAngles.z);

        if (!Application.isPlaying)
        {
            UniversalRenderPipeline.RenderSingleCamera(context, reflectionCamera);
        }

        reflectionCamera.transform.position = oldPosition;
        GL.invertCulling = false;
        material.SetTexture(IDs.Scene.reflectionTexture, reflectionTexture);
        material.SetFloat(IDs.Scene.reflectionTransparent, transparent);

        isRendering = false;
    }
Beispiel #17
0
    void OnBeginCameraRendering(ScriptableRenderContext context, Camera camera)
    {
        if (!enabled || !GetComponent <Renderer>() || !GetComponent <Renderer>().sharedMaterial || !GetComponent <Renderer>().enabled)
        {
            return;
        }
        if (camera != Camera.main)
        {
#if UNITY_EDITOR
            if (SceneView.lastActiveSceneView != null)
            {
                if (camera != SceneView.lastActiveSceneView.camera)
                {
                    return;
                }
            }
            else
            {
                return;
            }
                #else
            return;
                #endif
        }
        Camera cam = camera;        //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;

        // Optionally disable pixel lights for reflection
        int oldPixelLightCount = QualitySettings.pixelLightCount;
        if (m_DisablePixelLights)
        {
            QualitySettings.pixelLightCount = 0;
        }

        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;
        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  = CameraSpacePlane(reflectionCamera, pos, normal, 1.0f);
        Matrix4x4 projection = cam.projectionMatrix;
        CalculateObliqueMatrix(ref projection, clipPlane);
        reflectionCamera.projectionMatrix = projection;

        reflectionCamera.cullingMask   = ~(1 << 4) & m_ReflectLayers.value;       // never render water layer
        reflectionCamera.targetTexture = m_ReflectionTexture;
        //GL.SetRevertBackfacing(true);
        GL.invertCulling = true;
        reflectionCamera.transform.position = newpos;
        Vector3 euler = cam.transform.eulerAngles;
        reflectionCamera.transform.eulerAngles = new Vector3(0, euler.y, euler.z);
        reflectionCamera.depthTextureMode      = DepthTextureMode.Depth;
        // reflectionCamera.Render();
        UniversalRenderPipeline.RenderSingleCamera(context, reflectionCamera);

        // copy depth
        Graphics.SetRenderTarget(m_ReflectionDepthTexture);
        m_matCopyDepth.SetPass(0);
        DrawFullscreenQuad();
        Graphics.SetRenderTarget(null);
        // Graphics.Blit(m_ReflectionTexture, m_ReflectionDepthTexture, m_matCopyDepth);


        reflectionCamera.transform.position = oldpos;
        //GL.SetRevertBackfacing(false);
        GL.invertCulling = false;
        Material[] materials = GetComponent <Renderer>().sharedMaterials;
        foreach (Material mat in materials)
        {
            mat.SetTexture("_ReflectionTex", m_ReflectionTexture);
            mat.SetTexture("_ReflectionDepthTex", m_ReflectionDepthTexture);
        }

        // // Set matrix on the shader that transforms UVs from object space into screen
        // // space. We want to just project reflection texture on screen.
        // Matrix4x4 scaleOffset = Matrix4x4.TRS(
        //  new Vector3(0.5f, 0.5f, 0.5f), Quaternion.identity, new Vector3(0.5f, 0.5f, 0.5f));
        // Vector3 scale = transform.lossyScale;
        // Matrix4x4 mtx = transform.localToWorldMatrix * Matrix4x4.Scale(new Vector3(1.0f / scale.x, 1.0f / scale.y, 1.0f / scale.z));
        // mtx = scaleOffset * cam.projectionMatrix * cam.worldToCameraMatrix * mtx;
        // foreach (Material mat in materials)
        // {
        //  mat.SetMatrix("_ProjMatrix", mtx);
        // }

        // Restore pixel light count
        if (m_DisablePixelLights)
        {
            QualitySettings.pixelLightCount = oldPixelLightCount;
        }

        s_InsideRendering = false;
    }
Beispiel #18
0
        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;
        }
Beispiel #19
0
    private void RenderCamera(Camera camera, Renderer rend, Camera.StereoscopicEye eye, ref RenderTexture portalTexture, ScriptableRenderContext SRC)
    {
        // Create the camera that will render the reflection
        Camera portalCamera;

        CreatePortalCamera(camera, eye, out portalCamera, ref portalTexture);
        CopyCameraProperties(camera, portalCamera); // Copy the properties of the (player) camera

        // find out the reflection plane: position and normal in world space
        Vector3 pos    = transform.position;                                //portalRenderPlane.transform.forward;//
        Vector3 normal = transform.TransformDirection(projectionDirection); // Alex: This is done because sometimes the object reflection direction does not align with what was the default (transform.forward), in this way, the user can specify this.
        //normal.Normalize(); // Alex: normalize in case someone enters a non-normalized vector. Turned off for now because it is a fun effect :P

        // Optionally disable pixel lights for reflection
        int oldPixelLightCount = QualitySettings.pixelLightCount;

        if (m_DisablePixelLights)
        {
            QualitySettings.pixelLightCount = 0;
        }

        // 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.identity;

        CalculateReflectionMatrix(ref reflection, reflectionPlane);

        // Calculate the Eye offsets
        Vector3   oldEyePos;
        Matrix4x4 worldToCameraMatrix;

        if (camera.stereoEnabled)
        {
            Vector3 eyeOffset;
            worldToCameraMatrix = camera.GetStereoViewMatrix(eye);

            InputTracking.GetNodeStates(nodeStates);
            XRNodeState leftEyeState  = findNode(nodeStates, XRNode.LeftEye);
            XRNodeState rightEyeState = findNode(nodeStates, XRNode.RightEye);

            if (eye == Camera.StereoscopicEye.Left)
            {
                leftEyeState.TryGetPosition(out eyeOffset); //eyeOffset = InputTracking.GetLocalPosition(XRNode.LeftEye); //<< Deprecated
            }
            else
            {
                rightEyeState.TryGetPosition(out eyeOffset); //eyeOffset = InputTracking.GetLocalPosition(XRNode.RightEye); //<< Deprecated
            }
            eyeOffset.z = 0.0f;
            oldEyePos   = camera.transform.position + camera.transform.TransformVector(eyeOffset);
        }
        else
        {
            worldToCameraMatrix = camera.worldToCameraMatrix;
            oldEyePos           = camera.transform.position;
        }

        // >>>Transform Camera<<<
        portalCamera.projectionMatrix = camera.projectionMatrix; // Match matrices <<<
        Vector3 newEyePos = reflection.MultiplyPoint(oldEyePos);

        portalCamera.transform.position = newEyePos;

        portalCamera.worldToCameraMatrix = 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 = CameraSpacePlane(worldToCameraMatrix * reflection, pos, normal, 1.0f);

        Matrix4x4 projectionMatrix;

        if (camera.stereoEnabled)
        {
            projectionMatrix = camera.GetStereoProjectionMatrix(eye);
        }
        else
        {
            projectionMatrix = camera.projectionMatrix;
        }

        MakeProjectionMatrixOblique(ref projectionMatrix, clipPlane);

        portalCamera.projectionMatrix = projectionMatrix;
        portalCamera.cullingMask      = m_LayerMask.value; // Set culling mask <<<<
        portalCamera.targetTexture    = portalTexture;     // Set the target texture <<<

        GL.invertCulling = true;

        portalCamera.transform.rotation = camera.transform.rotation;

        UniversalRenderPipeline.RenderSingleCamera(SRC, portalCamera); // URP Version of: portalCamera.Render();

        GL.invertCulling = false;

        // Assign the rendertexture to the material
        Material[] materials = rend.sharedMaterials; // Why only get the shared materials?
        string     property  = "_ReflectionTex" + eye.ToString();

        foreach (Material mat in materials)
        {
            if (mat.HasProperty(property))
            {
                mat.SetTexture(property, portalTexture);
            }
        }

        // Restore pixel light count
        if (m_DisablePixelLights)
        {
            QualitySettings.pixelLightCount = oldPixelLightCount;
        }

        s_InsideRendering = false;
    }
        private void OnWillRenderCamera(ScriptableRenderContext context, Camera camera)
        {
#if SWS_DEV
            UnityEngine.Profiling.Profiler.BeginSample("Planar Reflections");
#endif
            //Skip for any special use camera's (except scene view camera)
            if (camera.cameraType != CameraType.SceneView && (camera.cameraType == CameraType.Reflection ||
                                                              camera.cameraType == CameraType.Preview ||
                                                              camera.hideFlags != HideFlags.None))
            {
                return;
            }

            isRendering = IsVisible(camera);

            //Note: Scene camera still rendering even if window not focused!
            if (isRendering == false)
            {
                return;
            }

            cameraData = camera.GetComponent <UniversalAdditionalCameraData>();
            if (cameraData && cameraData.renderType == CameraRenderType.Overlay)
            {
                return;
            }

            reflectionCameras.TryGetValue(camera, out reflectionCamera);
            if (reflectionCamera == null)
            {
                CreateReflectionCamera(camera);
            }

            //It's possible it is destroyed at this point when disabling reflections
            if (!reflectionCamera)
            {
                return;
            }

            if (renderScale != m_renderScale)
            {
                RenderTexture.ReleaseTemporary(reflectionCamera.targetTexture);
                CreateRenderTexture(reflectionCamera, camera);

                m_renderScale = renderScale;
            }

            UpdateWaterProperties(reflectionCamera);

#if UNITY_EDITOR
            //Screen pos outside of frustrum
            if (camera.orthographic && Vector3.Dot(Vector3.up, camera.transform.up) > 0.9999f)
            {
                return;
            }
#endif

            UpdatePerspective(camera, reflectionCamera);

            reflectionCamera.clearFlags = includeSkybox ? CameraClearFlags.Skybox : CameraClearFlags.Depth;

            bool fogEnabled = RenderSettings.fog;
            //Fog is based on clip-space z-distance and doesn't work with oblique projections
            if (fogEnabled)
            {
                RenderSettings.fog = false;
            }
            int maxLODLevel = QualitySettings.maximumLODLevel;
            QualitySettings.maximumLODLevel = maximumLODLevel;
            GL.invertCulling = true;

            UniversalRenderPipeline.RenderSingleCamera(context, reflectionCamera);

            if (fogEnabled)
            {
                RenderSettings.fog = true;
            }
            QualitySettings.maximumLODLevel = maxLODLevel;
            GL.invertCulling = false;

#if SWS_DEV
            UnityEngine.Profiling.Profiler.EndSample();
#endif
        }
        public void BeginCameraRendering(ScriptableRenderContext context, Camera camera)
        {
            if (camera != _camViewpoint)
            {
                return;
            }


            if (!RequestRefresh(Time.renderedFrameCount))
            {
                return; // Skip if not need to refresh on this frame
            }
            if (OceanRenderer.Instance == null)
            {
                return;
            }

            CreateWaterObjects(_camViewpoint);

            if (!_camReflections)
            {
                return;
            }

            // Find out the reflection plane: position and normal in world space
            Vector3 planePos    = OceanRenderer.Instance.Root.position;
            Vector3 planeNormal = Vector3.up;

            // Optionally disable pixel lights for reflection/refraction
            int oldPixelLightCount = QualitySettings.pixelLightCount;

            if (_disablePixelLights)
            {
                QualitySettings.pixelLightCount = 0;
            }

            UpdateCameraModes();

            // Reflect camera around reflection plane
            float   d = -Vector3.Dot(planeNormal, planePos) - _clipPlaneOffset;
            Vector4 reflectionPlane = new Vector4(planeNormal.x, planeNormal.y, planeNormal.z, d);

            Matrix4x4 reflection = Matrix4x4.zero;

            CalculateReflectionMatrix(ref reflection, reflectionPlane);
            Vector3 newpos = reflection.MultiplyPoint(_camViewpoint.transform.position);

            _camReflections.worldToCameraMatrix = _camViewpoint.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 = CameraSpacePlane(_camReflections, planePos, planeNormal, 1.0f);

            _camReflections.projectionMatrix = _camViewpoint.CalculateObliqueMatrix(clipPlane);

            // Set custom culling matrix from the current camera
            _camReflections.cullingMatrix = _camViewpoint.projectionMatrix * _camViewpoint.worldToCameraMatrix;

            _camReflections.targetTexture = _reflectionTexture;

            // Invert culling because view is mirrored
            bool oldCulling = GL.invertCulling;

            GL.invertCulling = !oldCulling;

            _camReflections.transform.position = newpos;
            Vector3 euler = _camViewpoint.transform.eulerAngles;

            _camReflections.transform.eulerAngles = new Vector3(-euler.x, euler.y, euler.z);
            _camReflections.cullingMatrix         = _camReflections.projectionMatrix * _camReflections.worldToCameraMatrix;

            ForceDistanceCulling(_farClipPlane);

            UniversalRenderPipeline.RenderSingleCamera(context, _camReflections);

            GL.invertCulling = oldCulling;

            // Restore pixel light count
            if (_disablePixelLights)
            {
                QualitySettings.pixelLightCount = oldPixelLightCount;
            }

            // Remember this frame as last refreshed
            Refreshed(Time.renderedFrameCount);
        }
Beispiel #22
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);
     }
 }
Beispiel #23
0
    private void UpdateCameras(ScriptableRenderContext context, Camera mainCam)
    {
        if (mainCam.cameraType == CameraType.Reflection || mainCam.cameraType == CameraType.Preview)
        {
            return;
        }

        var iceMat   = ResourceLoader.Get <Material>("Ice");
        var iceTiles = from obj in objects where obj.CompareTag("Ice") group obj by(int) obj.transform.position.y into g select g;

        foreach (var key in iceGroups.Keys.ToArray())
        {
            if (!iceTiles.Any(kv => kv.Key == key))
            {
                DestroyImmediate(iceGroups[key].reflectionCamera.gameObject);
                DestroyImmediate(iceGroups[key].material);
                iceGroups.Remove(key);
            }
        }
        foreach (var kv in iceTiles)
        {
            if (!iceGroups.ContainsKey(kv.Key))
            {
                var reflectionCam = new GameObject("IceReflectionCamera").AddComponent <Camera>();
                reflectionCam.cameraType = CameraType.Reflection;
                var reflectionTex = new RenderTexture(256, 256, 16);
                reflectionCam.targetTexture = reflectionTex;
                //reflectionCam.cullingMask = ~(1 << LayerMask.NameToLayer("Ice"));
                reflectionCam.gameObject.hideFlags = HideFlags.HideAndDontSave;

                var mat = Instantiate(iceMat);
                mat.name = iceMat.name + kv.Key;
                mat.SetTexture("_ReflectionTex", reflectionTex);

                iceGroups.Add(kv.Key, new IceGroup(mat, reflectionCam));
            }
            foreach (var obj in kv)
            {
                obj.GetComponent <Renderer>().sharedMaterial = iceGroups[kv.Key].material;
            }
        }

        Matrix4x4 getReflection(Vector3 p)
        {
            Vector3 n = Vector3.up;
            float   d = -Vector3.Dot(n, p);

            return(new Matrix4x4()
            {
                m00 = (1f - 2f * n.x * n.x),
                m01 = (-2f * n.x * n.y),
                m02 = (-2f * n.x * n.z),
                m03 = (-2f * d * n.x),
                m10 = (-2f * n.y * n.x),
                m11 = (1f - 2f * n.y * n.y),
                m12 = (-2f * n.y * n.z),
                m13 = (-2f * d * n.y),
                m20 = (-2f * n.z * n.x),
                m21 = (-2f * n.z * n.y),
                m22 = (1f - 2f * n.z * n.z),
                m23 = (-2f * d * n.z),
                m30 = 0f,
                m31 = 0f,
                m32 = 0f,
                m33 = 1f,
            });
        }

        var mainCamPos   = mainCam.transform.position;
        var mainCamEuler = mainCam.transform.eulerAngles;

        foreach (var kv in iceGroups)
        {
            float  y             = kv.Key - 0.498f;
            Camera reflectionCam = kv.Value.reflectionCamera;
            reflectionCam.transform.position    = new Vector3(mainCamPos.x, 2 * y - mainCamPos.y, mainCamPos.z);
            reflectionCam.transform.eulerAngles = new Vector3(-mainCamEuler.x, mainCamEuler.y, mainCamEuler.z);

            var reflection = getReflection(new Vector3(mainCamPos.x, y, mainCamPos.z));
            reflectionCam.worldToCameraMatrix = mainCam.worldToCameraMatrix * reflection;

            var p = reflectionCam.worldToCameraMatrix.MultiplyPoint(new Vector3(mainCamPos.x, y, mainCamPos.z));
            var n = reflectionCam.worldToCameraMatrix.MultiplyVector(Vector3.up).normalized;
            reflectionCam.projectionMatrix = mainCam.CalculateObliqueMatrix(new Vector4(n.x, n.y, n.z, -Vector3.Dot(p, n)));

            GL.invertCulling = true;
            UniversalRenderPipeline.RenderSingleCamera(context, reflectionCam);
            GL.invertCulling = false;
        }
    }