public void Setup(ScriptableRenderer renderer, ref RenderingData renderingData)
        {
            Init();

            Camera camera = renderingData.cameraData.camera;

            renderer.SetupPerObjectLightIndices(ref renderingData.cullResults, ref renderingData.lightData);
            RenderTextureDescriptor baseDescriptor = ScriptableRenderer.CreateRenderTextureDescriptor(ref renderingData.cameraData);
            ClearFlag clearFlag = ScriptableRenderer.GetCameraClearFlag(renderingData.cameraData.camera);
            RenderTextureDescriptor shadowDescriptor = baseDescriptor;

            shadowDescriptor.dimension = TextureDimension.Tex2D;

            bool mainLightShadows = false;

            if (renderingData.shadowData.supportsMainLightShadows)
            {
                mainLightShadows = m_MainLightShadowCasterPass.Setup(m_MainLightShadowmap, ref renderingData);
                if (mainLightShadows)
                {
                    renderer.EnqueuePass(m_MainLightShadowCasterPass);
                }
            }

            if (renderingData.shadowData.supportsAdditionalLightShadows)
            {
                bool additionalLightShadows = m_AdditionalLightsShadowCasterPass.Setup(m_AdditionalLightsShadowmap, ref renderingData, renderer.maxVisibleAdditionalLights);
                if (additionalLightShadows)
                {
                    renderer.EnqueuePass(m_AdditionalLightsShadowCasterPass);
                }
            }

            bool resolveShadowsInScreenSpace = mainLightShadows && renderingData.shadowData.requiresScreenSpaceShadowResolve;

            // Depth prepass is generated in the following cases:
            // - We resolve shadows in screen space
            // - Scene view camera always requires a depth texture. We do a depth pre-pass to simplify it and it shouldn't matter much for editor.
            // - If game or offscreen camera requires it we check if we can copy the depth from the rendering opaques pass and use that instead.
            bool requiresDepthPrepass = resolveShadowsInScreenSpace ||
                                        renderingData.cameraData.isSceneViewCamera ||
                                        (renderingData.cameraData.requiresDepthTexture && (!CanCopyDepth(ref renderingData.cameraData)));

            // For now VR requires a depth prepass until we figure out how to properly resolve texture2DMS in stereo
            requiresDepthPrepass |= renderingData.cameraData.isStereoEnabled;

            renderer.EnqueuePass(m_SetupForwardRenderingPass);

            camera.GetComponents(m_BeforeRenderPasses);
            camera.GetComponents(m_AfterOpaquePasses);
            camera.GetComponents(m_AfterOpaquePostProcessPasses);
            camera.GetComponents(m_AfterSkyboxPasses);
            camera.GetComponents(m_AfterTransparentPasses);
            camera.GetComponents(m_AfterRenderPasses);

            bool createColorTexture = RequiresIntermediateColorTexture(ref renderingData, baseDescriptor) ||
                                      m_BeforeRenderPasses.Count != 0 ||
                                      m_AfterOpaquePasses.Count != 0 ||
                                      m_AfterOpaquePostProcessPasses.Count != 0 ||
                                      m_AfterSkyboxPasses.Count != 0 ||
                                      m_AfterTransparentPasses.Count != 0 ||
                                      m_AfterRenderPasses.Count != 0;

            // If camera requires depth and there's no depth pre-pass we create a depth texture that can be read
            // later by effect requiring it.
            bool createDepthTexture = renderingData.cameraData.requiresDepthTexture && !requiresDepthPrepass;

            RenderTargetHandle colorHandle = (createColorTexture) ? m_ColorAttachment : RenderTargetHandle.CameraTarget;
            RenderTargetHandle depthHandle = (createDepthTexture) ? m_DepthAttachment : RenderTargetHandle.CameraTarget;

            var sampleCount = (SampleCount)renderingData.cameraData.msaaSamples;

            if (createColorTexture || createDepthTexture)
            {
                m_CreateLightweightRenderTexturesPass.Setup(baseDescriptor, colorHandle, depthHandle, sampleCount);
                renderer.EnqueuePass(m_CreateLightweightRenderTexturesPass);
            }

            foreach (var pass in m_BeforeRenderPasses)
            {
                renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle, clearFlag));
            }

            if (requiresDepthPrepass)
            {
                m_DepthOnlyPass.Setup(baseDescriptor, m_DepthTexture);
                renderer.EnqueuePass(m_DepthOnlyPass);
            }

            if (resolveShadowsInScreenSpace)
            {
                m_ScreenSpaceShadowResolvePass.Setup(baseDescriptor, m_ScreenSpaceShadowmap);
                renderer.EnqueuePass(m_ScreenSpaceShadowResolvePass);
            }

            if (renderingData.cameraData.isStereoEnabled)
            {
                renderer.EnqueuePass(m_BeginXrRenderingPass);
            }

            var perObjectFlags = ScriptableRenderer.GetPerObjectLightFlags(renderingData.lightData.mainLightIndex, renderingData.lightData.additionalLightsCount);

            m_SetupLightweightConstants.Setup(renderer.maxVisibleAdditionalLights, renderer.perObjectLightIndices);
            renderer.EnqueuePass(m_SetupLightweightConstants);

            // If a before all render pass executed we expect it to clear the color render target
            if (m_BeforeRenderPasses.Count != 0)
            {
                clearFlag = ClearFlag.None;
            }

            m_RenderOpaqueForwardPass.Setup(baseDescriptor, colorHandle, depthHandle, clearFlag, camera.backgroundColor, perObjectFlags);
            renderer.EnqueuePass(m_RenderOpaqueForwardPass);
            foreach (var pass in m_AfterOpaquePasses)
            {
                renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
            }

            if (renderingData.cameraData.postProcessEnabled &&
                renderingData.cameraData.postProcessLayer.HasOpaqueOnlyEffects(renderer.postProcessingContext))
            {
                m_OpaquePostProcessPass.Setup(baseDescriptor, colorHandle, colorHandle, true, false);
                renderer.EnqueuePass(m_OpaquePostProcessPass);

                foreach (var pass in m_AfterOpaquePostProcessPasses)
                {
                    renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
                }
            }

            if (camera.clearFlags == CameraClearFlags.Skybox && RenderSettings.skybox != null)
            {
                // We can't combine skybox and render opaques passes if there's a custom render pass in between
                // them. Ideally we need a render graph here that each render pass declares inputs and output
                // attachments and their Load/Store action so we figure out properly if we can combine passes
                // and move to interleaved rendering with RenderPass API.
                bool combineWithRenderOpaquesPass = m_AfterOpaquePostProcessPasses.Count == 0;
                m_DrawSkyboxPass.Setup(baseDescriptor, colorHandle, depthHandle, combineWithRenderOpaquesPass);
                renderer.EnqueuePass(m_DrawSkyboxPass);
            }

            foreach (var pass in m_AfterSkyboxPasses)
            {
                renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
            }

            // If a depth texture was created we necessarily need to copy it, otherwise we could have render it to a renderbuffer
            if (createDepthTexture)
            {
                m_CopyDepthPass.Setup(depthHandle, m_DepthTexture);
                renderer.EnqueuePass(m_CopyDepthPass);
            }

            if (renderingData.cameraData.requiresOpaqueTexture)
            {
                m_CopyColorPass.Setup(colorHandle, m_OpaqueColor);
                renderer.EnqueuePass(m_CopyColorPass);
            }

            m_RenderTransparentForwardPass.Setup(baseDescriptor, colorHandle, depthHandle, perObjectFlags);
            renderer.EnqueuePass(m_RenderTransparentForwardPass);

            foreach (var pass in m_AfterTransparentPasses)
            {
                renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
            }

#if UNITY_EDITOR
            m_LitGizmoRenderingPass.Setup(true);
            renderer.EnqueuePass(m_LitGizmoRenderingPass);
#endif

            bool afterRenderExists = m_AfterRenderPasses.Count != 0;

            // if we have additional filters
            // we need to stay in a RT
            if (afterRenderExists)
            {
                // perform post with src / dest the same
                if (renderingData.cameraData.postProcessEnabled)
                {
                    m_PostProcessPass.Setup(baseDescriptor, colorHandle, colorHandle, false, false);
                    renderer.EnqueuePass(m_PostProcessPass);
                }

                //execute after passes
                foreach (var pass in m_AfterRenderPasses)
                {
                    renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
                }

                //now blit into the final target
                if (colorHandle != RenderTargetHandle.CameraTarget)
                {
                    if (m_CapturePass.Setup(colorHandle, renderingData.cameraData.captureActions))
                    {
                        renderer.EnqueuePass(m_CapturePass);
                    }

                    m_FinalBlitPass.Setup(baseDescriptor, colorHandle, Display.main.requiresSrgbBlitToBackbuffer, renderingData.killAlphaInFinalBlit);
                    renderer.EnqueuePass(m_FinalBlitPass);
                }
            }
            else
            {
                if (renderingData.cameraData.postProcessEnabled)
                {
                    m_PostProcessPass.Setup(baseDescriptor, colorHandle, RenderTargetHandle.CameraTarget, false, renderingData.cameraData.camera.targetTexture == null);
                    renderer.EnqueuePass(m_PostProcessPass);
                }
                else if (colorHandle != RenderTargetHandle.CameraTarget)
                {
                    if (m_CapturePass.Setup(colorHandle, renderingData.cameraData.captureActions))
                    {
                        renderer.EnqueuePass(m_CapturePass);
                    }

                    m_FinalBlitPass.Setup(baseDescriptor, colorHandle, Display.main.requiresSrgbBlitToBackbuffer, renderingData.killAlphaInFinalBlit);
                    renderer.EnqueuePass(m_FinalBlitPass);
                }
            }

            if (renderingData.cameraData.isStereoEnabled)
            {
                renderer.EnqueuePass(m_EndXrRenderingPass);
            }

#if UNITY_EDITOR
            m_UnlitGizmoRenderingPass.Setup(false);
            renderer.EnqueuePass(m_UnlitGizmoRenderingPass);

            if (renderingData.cameraData.isSceneViewCamera)
            {
                m_SceneViewDepthCopyPass.Setup(m_DepthTexture);
                renderer.EnqueuePass(m_SceneViewDepthCopyPass);
            }
#endif
        }
예제 #2
0
        public void Setup(ScriptableRenderer renderer, ref RenderingData renderingData)
        {
            Init();

            Camera camera = renderingData.cameraData.camera;

            renderer.SetupPerObjectLightIndices(ref renderingData.cullResults, ref renderingData.lightData);
            RenderTextureDescriptor baseDescriptor   = ScriptableRenderer.CreateRenderTextureDescriptor(ref renderingData.cameraData);
            RenderTextureDescriptor shadowDescriptor = baseDescriptor;

            shadowDescriptor.dimension = TextureDimension.Tex2D;

            bool mainLightShadows = false;

            if (renderingData.shadowData.supportsMainLightShadows)
            {
                mainLightShadows = m_MainLightShadowCasterPass.Setup(m_MainLightShadowmap, ref renderingData);
                if (mainLightShadows)
                {
                    renderer.EnqueuePass(m_MainLightShadowCasterPass);
                }
            }

            if (renderingData.shadowData.supportsAdditionalLightShadows)
            {
                bool additionalLightShadows = m_AdditionalLightsShadowCasterPass.Setup(m_AdditionalLightsShadowmap, ref renderingData, renderer.maxVisibleAdditionalLights);
                if (additionalLightShadows)
                {
                    renderer.EnqueuePass(m_AdditionalLightsShadowCasterPass);
                }
            }

            bool resolveShadowsInScreenSpace = mainLightShadows && renderingData.shadowData.requiresScreenSpaceShadowResolve;
            bool requiresDepthPrepass        = resolveShadowsInScreenSpace || renderingData.cameraData.isSceneViewCamera ||
                                               (renderingData.cameraData.requiresDepthTexture && (!CanCopyDepth(ref renderingData.cameraData)));

            // For now VR requires a depth prepass until we figure out how to properly resolve texture2DMS in stereo
            requiresDepthPrepass |= renderingData.cameraData.isStereoEnabled;

            renderer.EnqueuePass(m_SetupForwardRenderingPass);

            camera.GetComponents(m_AfterDepthpasses);
            camera.GetComponents(m_AfterOpaquePasses);
            camera.GetComponents(m_AfterOpaquePostProcessPasses);
            camera.GetComponents(m_AfterSkyboxPasses);
            camera.GetComponents(m_AfterTransparentPasses);
            camera.GetComponents(m_AfterRenderPasses);

            if (requiresDepthPrepass)
            {
                m_DepthOnlyPass.Setup(baseDescriptor, m_DepthTexture, SampleCount.One);
                renderer.EnqueuePass(m_DepthOnlyPass);

                foreach (var pass in m_AfterDepthpasses)
                {
                    renderer.EnqueuePass(pass.GetPassToEnqueue(m_DepthOnlyPass.descriptor, m_DepthTexture));
                }
            }

            if (resolveShadowsInScreenSpace)
            {
                m_ScreenSpaceShadowResolvePass.Setup(baseDescriptor, m_ScreenSpaceShadowmap);
                renderer.EnqueuePass(m_ScreenSpaceShadowResolvePass);
            }

            bool requiresRenderToTexture = RequiresIntermediateColorTexture(ref renderingData.cameraData, baseDescriptor) ||
                                           m_AfterDepthpasses.Count != 0 ||
                                           m_AfterOpaquePasses.Count != 0 ||
                                           m_AfterOpaquePostProcessPasses.Count != 0 ||
                                           m_AfterSkyboxPasses.Count != 0 ||
                                           m_AfterTransparentPasses.Count != 0 ||
                                           m_AfterRenderPasses.Count != 0 ||
                                           Display.main.requiresBlitToBackbuffer ||
                                           renderingData.killAlphaInFinalBlit;

            RenderTargetHandle colorHandle = RenderTargetHandle.CameraTarget;
            RenderTargetHandle depthHandle = RenderTargetHandle.CameraTarget;


            var sampleCount = (SampleCount)renderingData.cameraData.msaaSamples;

            if (requiresRenderToTexture)
            {
                colorHandle = m_ColorAttachment;
                depthHandle = m_DepthAttachment;

                m_CreateLightweightRenderTexturesPass.Setup(baseDescriptor, colorHandle, depthHandle, sampleCount);
                renderer.EnqueuePass(m_CreateLightweightRenderTexturesPass);
            }

            if (renderingData.cameraData.isStereoEnabled)
            {
                renderer.EnqueuePass(m_BeginXrRenderingPass);
            }

            var perObjectFlags = ScriptableRenderer.GetPerObjectLightFlags(renderingData.lightData.mainLightIndex, renderingData.lightData.additionalLightsCount);

            m_SetupLightweightConstants.Setup(renderer.maxVisibleAdditionalLights, renderer.perObjectLightIndices);
            renderer.EnqueuePass(m_SetupLightweightConstants);

            m_RenderOpaqueForwardPass.Setup(baseDescriptor, colorHandle, depthHandle, ScriptableRenderer.GetCameraClearFlag(camera), camera.backgroundColor, perObjectFlags);
            renderer.EnqueuePass(m_RenderOpaqueForwardPass);
            foreach (var pass in m_AfterOpaquePasses)
            {
                renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
            }

            if (renderingData.cameraData.postProcessEnabled &&
                renderingData.cameraData.postProcessLayer.HasOpaqueOnlyEffects(renderer.postProcessingContext))
            {
                m_CreatePostOpaqueColorPass.Setup(baseDescriptor, m_ColorAttachmentAfterOpaquePost, sampleCount);
                renderer.EnqueuePass(m_CreatePostOpaqueColorPass);
                m_OpaquePostProcessPass.Setup(baseDescriptor, colorHandle, m_ColorAttachmentAfterOpaquePost, true, false);
                renderer.EnqueuePass(m_OpaquePostProcessPass);

                colorHandle = m_ColorAttachmentAfterOpaquePost;

                foreach (var pass in m_AfterOpaquePostProcessPasses)
                {
                    renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
                }
            }

            if (camera.clearFlags == CameraClearFlags.Skybox)
            {
                m_DrawSkyboxPass.Setup(colorHandle, depthHandle);
                renderer.EnqueuePass(m_DrawSkyboxPass);
            }

            foreach (var pass in m_AfterSkyboxPasses)
            {
                renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
            }

            if (renderingData.cameraData.requiresDepthTexture && !requiresDepthPrepass)
            {
                m_CopyDepthPass.Setup(depthHandle, m_DepthTexture);
                renderer.EnqueuePass(m_CopyDepthPass);
            }

            if (renderingData.cameraData.requiresOpaqueTexture)
            {
                m_CopyColorPass.Setup(colorHandle, m_OpaqueColor);
                renderer.EnqueuePass(m_CopyColorPass);
            }

            m_RenderTransparentForwardPass.Setup(baseDescriptor, colorHandle, depthHandle, perObjectFlags);
            renderer.EnqueuePass(m_RenderTransparentForwardPass);

            foreach (var pass in m_AfterTransparentPasses)
            {
                renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
            }

#if UNITY_EDITOR
            m_LitGizmoRenderingPass.Setup(true);
            renderer.EnqueuePass(m_LitGizmoRenderingPass);
#endif

            bool afterRenderExists = m_AfterRenderPasses.Count != 0;

            // if we have additional filters
            // we need to stay in a RT
            if (afterRenderExists)
            {
                // perform post with src / dest the same
                if (renderingData.cameraData.postProcessEnabled)
                {
                    m_CreatePostTransparentColorPass.Setup(baseDescriptor, m_ColorAttachmentAfterTransparentPost, sampleCount);
                    renderer.EnqueuePass(m_CreatePostTransparentColorPass);

                    m_PostProcessPass.Setup(baseDescriptor, colorHandle, m_ColorAttachmentAfterTransparentPost, false, false);
                    renderer.EnqueuePass(m_PostProcessPass);

                    colorHandle = m_ColorAttachmentAfterTransparentPost;
                }

                //execute after passes
                foreach (var pass in m_AfterRenderPasses)
                {
                    renderer.EnqueuePass(pass.GetPassToEnqueue(baseDescriptor, colorHandle, depthHandle));
                }

                //now blit into the final target
                if (colorHandle != RenderTargetHandle.CameraTarget)
                {
                    if (m_CapturePass.Setup(colorHandle, renderingData.cameraData.captureActions))
                    {
                        renderer.EnqueuePass(m_CapturePass);
                    }

                    m_FinalBlitPass.Setup(baseDescriptor, colorHandle, Display.main.requiresSrgbBlitToBackbuffer, renderingData.killAlphaInFinalBlit);
                    renderer.EnqueuePass(m_FinalBlitPass);
                }
            }
            else
            {
                if (renderingData.cameraData.postProcessEnabled)
                {
                    m_PostProcessPass.Setup(baseDescriptor, colorHandle, RenderTargetHandle.CameraTarget, false, renderingData.cameraData.camera.targetTexture == null);
                    renderer.EnqueuePass(m_PostProcessPass);
                }
                else if (colorHandle != RenderTargetHandle.CameraTarget)
                {
                    if (m_CapturePass.Setup(colorHandle, renderingData.cameraData.captureActions))
                    {
                        renderer.EnqueuePass(m_CapturePass);
                    }

                    m_FinalBlitPass.Setup(baseDescriptor, colorHandle, Display.main.requiresSrgbBlitToBackbuffer, renderingData.killAlphaInFinalBlit);
                    renderer.EnqueuePass(m_FinalBlitPass);
                }
            }

            if (renderingData.cameraData.isStereoEnabled)
            {
                renderer.EnqueuePass(m_EndXrRenderingPass);
            }

#if UNITY_EDITOR
            m_UnlitGizmoRenderingPass.Setup(false);
            renderer.EnqueuePass(m_UnlitGizmoRenderingPass);

            if (renderingData.cameraData.isSceneViewCamera)
            {
                m_SceneViewDepthCopyPass.Setup(m_DepthTexture);
                renderer.EnqueuePass(m_SceneViewDepthCopyPass);
            }
#endif
        }