Esempio n. 1
0
        void OnPreCull()
        {
            // Unused in scriptable render pipelines
            if (RuntimeUtilities.scriptableRenderPipelineActive)
            {
                return;
            }

            var context      = m_CurrentContext;
            var sourceFormat = m_Camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;

            context.Reset();
            context.camera       = m_Camera;
            context.sourceFormat = sourceFormat;

            m_LegacyCmdBufferBeforeReflections.Clear();
            m_LegacyCmdBufferOpaque.Clear();
            m_LegacyCmdBuffer.Clear();

            SetupContext(context);

            // Lighting & opaque-only effects
            int  opaqueOnlyEffects          = 0;
            bool hasCustomOpaqueOnlyEffects = HasOpaqueOnlyEffects(context);
            bool isAmbientOcclusionDeferred = ambientOcclusion.IsEnabledAndSupported(context) && ambientOcclusion.IsAmbientOnly(context);
            bool isAmbientOcclusionOpaque   = ambientOcclusion.IsEnabledAndSupported(context) && !ambientOcclusion.IsAmbientOnly(context);
            bool isFogActive = fog.IsEnabledAndSupported(context);

            // Ambient-only AO is done in a separate command buffer, before reflections
            if (isAmbientOcclusionDeferred)
            {
                context.command = m_LegacyCmdBufferBeforeReflections;
                ambientOcclusion.RenderAmbientOnly(context);
            }
            else if (isAmbientOcclusionOpaque)
            {
                opaqueOnlyEffects++;
            }

            opaqueOnlyEffects += isFogActive ? 1 : 0;
            opaqueOnlyEffects += hasCustomOpaqueOnlyEffects ? 1 : 0;

            var cameraTarget = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget);

            if (opaqueOnlyEffects > 0)
            {
                var cmd = m_LegacyCmdBufferOpaque;
                context.command = cmd;

                // We need to use the internal Blit method to copy the camera target or it'll fail
                // on tiled GPU as it won't be able to resolve
                int tempTarget0 = m_TargetPool.Get();
                cmd.GetTemporaryRT(tempTarget0, context.width, context.height, 24, FilterMode.Bilinear, sourceFormat);
                cmd.Blit(cameraTarget, tempTarget0);
                context.source = tempTarget0;

                int tempTarget1 = -1;

                if (opaqueOnlyEffects > 1)
                {
                    tempTarget1 = m_TargetPool.Get();
                    cmd.GetTemporaryRT(tempTarget1, context.width, context.height, 24, FilterMode.Bilinear, sourceFormat);
                    context.destination = tempTarget1;
                }
                else
                {
                    context.destination = cameraTarget;
                }

                if (isAmbientOcclusionOpaque)
                {
                    ambientOcclusion.RenderAfterOpaque(context);
                    opaqueOnlyEffects--;
                    var prevSource = context.source;
                    context.source      = context.destination;
                    context.destination = opaqueOnlyEffects == 1 ? cameraTarget : prevSource;
                }

                // TODO: Insert SSR here

                if (isFogActive)
                {
                    fog.Render(context);
                    opaqueOnlyEffects--;
                    var prevSource = context.source;
                    context.source      = context.destination;
                    context.destination = opaqueOnlyEffects == 1 ? cameraTarget : prevSource;
                }

                if (hasCustomOpaqueOnlyEffects)
                {
                    RenderOpaqueOnly(context);
                }

                if (opaqueOnlyEffects > 1)
                {
                    cmd.ReleaseTemporaryRT(tempTarget1);
                }

                cmd.ReleaseTemporaryRT(tempTarget0);
            }

            // Post-transparency stack
            // Same as before, first blit needs to use the builtin Blit command to properly handle
            // tiled GPUs
            int tempRt = m_TargetPool.Get();

            m_LegacyCmdBuffer.GetTemporaryRT(tempRt, context.width, context.height, 24, FilterMode.Bilinear, sourceFormat);
            m_LegacyCmdBuffer.SetGlobalTexture(ShaderIDs.MainTex, cameraTarget);
            m_LegacyCmdBuffer.Blit(cameraTarget, tempRt, RuntimeUtilities.copyMaterial, stopNaNPropagation ? 3 : 2);
            m_NaNKilled = stopNaNPropagation;

            context.command     = m_LegacyCmdBuffer;
            context.source      = tempRt;
            context.destination = cameraTarget;
            Render(context);
            m_LegacyCmdBuffer.ReleaseTemporaryRT(tempRt);
        }
        void OnPreCull()
        {
            // Unused in scriptable render pipelines
            if (RuntimeUtilities.scriptableRenderPipelineActive)
            {
                return;
            }

            var context      = m_CurrentContext;
            var sourceFormat = m_Camera.allowHDR ? RenderTextureFormat.DefaultHDR : RenderTextureFormat.Default;

            // Resets the projection matrix from previous frame in case TAA was enabled.
            // We also need to force reset the non-jittered projection matrix here as it's not done
            // when ResetProjectionMatrix() is called and will break transparent rendering if TAA
            // is switched off and the FOV or any other camera property changes.
            m_Camera.ResetProjectionMatrix();
            m_Camera.nonJitteredProjectionMatrix = m_Camera.projectionMatrix;

            context.Reset();
            context.camera       = m_Camera;
            context.sourceFormat = sourceFormat;

            m_LegacyCmdBufferBeforeReflections.Clear();
            m_LegacyCmdBufferBeforeLighting.Clear();
            m_LegacyCmdBufferOpaque.Clear();
            m_LegacyCmdBuffer.Clear();

            SetupContext(context);

            // Lighting & opaque-only effects
            int  opaqueOnlyEffects          = 0;
            bool hasCustomOpaqueOnlyEffects = HasOpaqueOnlyEffects(context);
            bool aoSupported   = ambientOcclusion.IsEnabledAndSupported(context);
            bool aoAmbientOnly = ambientOcclusion.IsAmbientOnly(context);
            bool isAmbientOcclusionDeferred = aoSupported && aoAmbientOnly;
            bool isAmbientOcclusionOpaque   = aoSupported && !aoAmbientOnly;
            bool isFogActive = fog.IsEnabledAndSupported(context);

            // Ambient-only AO is a special case and has to be done in separate command buffers
            if (isAmbientOcclusionDeferred)
            {
                var ao = ambientOcclusion.Get();

                // Render as soon as possible - should be done async in SRPs when available
                context.command = m_LegacyCmdBufferBeforeReflections;
                ao.RenderAmbientOnly(context);

                // Composite with GBuffer right before the lighting pass
                context.command = m_LegacyCmdBufferBeforeLighting;
                ao.CompositeAmbientOnly(context);
            }
            else if (isAmbientOcclusionOpaque)
            {
                context.command = m_LegacyCmdBufferOpaque;
                ambientOcclusion.Get().RenderAfterOpaque(context);
            }

            opaqueOnlyEffects += isFogActive ? 1 : 0;
            opaqueOnlyEffects += hasCustomOpaqueOnlyEffects ? 1 : 0;

            var cameraTarget = new RenderTargetIdentifier(BuiltinRenderTextureType.CameraTarget);

            if (opaqueOnlyEffects > 0)
            {
                var cmd = m_LegacyCmdBufferOpaque;
                context.command = cmd;

                // We need to use the internal Blit method to copy the camera target or it'll fail
                // on tiled GPU as it won't be able to resolve
                int tempTarget0 = m_TargetPool.Get();
                cmd.GetTemporaryRT(tempTarget0, context.width, context.height, 24, FilterMode.Bilinear, sourceFormat);
                cmd.Blit(cameraTarget, tempTarget0);
                context.source = tempTarget0;

                int tempTarget1 = -1;

                if (opaqueOnlyEffects > 1)
                {
                    tempTarget1 = m_TargetPool.Get();
                    cmd.GetTemporaryRT(tempTarget1, context.width, context.height, 24, FilterMode.Bilinear, sourceFormat);
                    context.destination = tempTarget1;
                }
                else
                {
                    context.destination = cameraTarget;
                }

                // TODO: Insert SSR here

                if (isFogActive)
                {
                    fog.Render(context);
                    opaqueOnlyEffects--;
                    var prevSource = context.source;
                    context.source      = context.destination;
                    context.destination = opaqueOnlyEffects == 1 ? cameraTarget : prevSource;
                }

                if (hasCustomOpaqueOnlyEffects)
                {
                    RenderOpaqueOnly(context);
                }

                if (opaqueOnlyEffects > 1)
                {
                    cmd.ReleaseTemporaryRT(tempTarget1);
                }

                cmd.ReleaseTemporaryRT(tempTarget0);
            }

            // Post-transparency stack
            // Same as before, first blit needs to use the builtin Blit command to properly handle
            // tiled GPUs
            int tempRt = m_TargetPool.Get();

            m_LegacyCmdBuffer.GetTemporaryRT(tempRt, context.width, context.height, 24, FilterMode.Bilinear, sourceFormat);
            m_LegacyCmdBuffer.Blit(cameraTarget, tempRt, RuntimeUtilities.copyStdMaterial, stopNaNPropagation ? 1 : 0);
            m_NaNKilled = stopNaNPropagation;

            context.command     = m_LegacyCmdBuffer;
            context.source      = tempRt;
            context.destination = cameraTarget;
            Render(context);
            m_LegacyCmdBuffer.ReleaseTemporaryRT(tempRt);
        }