void RenderDeferredLighting(Camera camera, RenderLoop renderLoop)
        {
            if (debugParameters.useForwardRenderingOnly)
            {
                return;
            }

            // Bind material data
            m_LitRenderLoop.Bind();

            var invViewProj = GetViewProjectionMatrix(camera).inverse;

            m_DeferredMaterial.SetMatrix("_InvViewProjMatrix", invViewProj);

            var screenSize = ComputeScreenSize(camera);

            m_DeferredMaterial.SetVector("_ScreenSize", screenSize);

            // m_gbufferManager.BindBuffers(m_DeferredMaterial);
            // TODO: Bind depth textures
            var cmd = new CommandBuffer {
                name = "Deferred Ligthing Pass"
            };

            cmd.Blit(null, new RenderTargetIdentifier(s_CameraColorBuffer), m_DeferredMaterial, 0);
            renderLoop.ExecuteCommandBuffer(cmd);
            cmd.Dispose();
        }
Exemplo n.º 2
0
        public override void Render(ScriptableRenderContext renderContext, Camera[] cameras)
        {
            base.Render(renderContext, cameras);

#if UNITY_EDITOR
            SupportedRenderingFeatures.active = s_NeededFeatures;
#endif

            GraphicsSettings.lightsUseLinearIntensity  = true;
            GraphicsSettings.lightsUseColorTemperature = true;

            m_SkyManager.Build();

            if (!m_LitRenderLoop.isInit)
            {
                m_LitRenderLoop.RenderInit(renderContext);
            }

            // Do anything we need to do upon a new frame.

            if (m_LightLoop != null)
            {
                m_LightLoop.NewFrame();
            }

            m_Owner.ApplyDebugParameters();
            m_Owner.UpdateCommonSettings();

            // Set Frame constant buffer
            // TODO...

            // we only want to render one camera for now
            // select the most main camera!

            Camera camera = cameras.OrderByDescending(x => x.tag == "MainCamera").FirstOrDefault();
            if (camera == null)
            {
                return;
            }

            // Set camera constant buffer
            // TODO...

            CullingParameters cullingParams;
            if (!CullResults.GetCullingParameters(camera, out cullingParams))
            {
                return;
            }

            m_ShadowPass.UpdateCullingParameters(ref cullingParams);

            var cullResults = CullResults.Cull(ref cullingParams, renderContext);

            Resize(camera);

            renderContext.SetupCameraProperties(camera);

            HDCamera hdCamera = Utilities.GetHDCamera(camera);

            // TODO: Find a correct place to bind these material textures
            // We have to bind the material specific global parameters in this mode
            m_LitRenderLoop.Bind();

            InitAndClearBuffer(camera, renderContext);

            RenderDepthPrepass(cullResults, camera, renderContext);

            // Forward opaque with deferred/cluster tile require that we fill the depth buffer
            // correctly to build the light list.
            // TODO: avoid double lighting by tagging stencil or gbuffer that we must not lit.
            RenderForwardOnlyOpaqueDepthPrepass(cullResults, camera, renderContext);
            RenderGBuffer(cullResults, camera, renderContext);

            // 'm_CameraStencilBufferRT' is a temporary copy of the stencil buffer and should be removed
            // once we are able to read from the depth buffer and perform the stencil test simultaneously.
            using (new Utilities.ProfilingSample("Copy depth-stencil buffer", renderContext))
            {
                var cmd = new CommandBuffer();
                cmd.CopyTexture(m_CameraDepthStencilBufferRT, m_CameraStencilBufferRT);
                renderContext.ExecuteCommandBuffer(cmd);
                cmd.Dispose();
            }

            if (debugParameters.debugViewMaterial != 0)
            {
                RenderDebugViewMaterial(cullResults, hdCamera, renderContext);
            }
            else
            {
                using (new Utilities.ProfilingSample("Shadow Pass", renderContext))
                {
                    m_ShadowPass.Render(renderContext, cullResults, out m_ShadowsResult);
                }

                renderContext.SetupCameraProperties(camera); // Need to recall SetupCameraProperties after m_ShadowPass.Render

                if (m_LightLoop != null)
                {
                    using (new Utilities.ProfilingSample("Build Light list", renderContext))
                    {
                        m_LightLoop.PrepareLightsForGPU(m_Owner.shadowSettings, cullResults, camera, ref m_ShadowsResult);
                        m_LightLoop.BuildGPULightLists(camera, renderContext, m_CameraDepthStencilBufferRT); // TODO: Use async compute here to run light culling during shadow
                    }
                }

                PushGlobalParams(hdCamera, renderContext);

                // Caution: We require sun light here as some sky use the sun light to render, mean UpdateSkyEnvironment
                // must be call after BuildGPULightLists.
                // TODO: Try to arrange code so we can trigger this call earlier and use async compute here to run sky convolution during other passes (once we move convolution shader to compute).
                UpdateSkyEnvironment(hdCamera, renderContext);

                RenderDeferredLighting(hdCamera, renderContext);

                // We compute subsurface scattering here. Therefore, no objects rendered afterwards will exhibit SSS.
                // Currently, there is no efficient way to switch between SRT and MRT for the forward pass;
                // therefore, forward-rendered objects do not output split lighting required for the SSS pass.
                CombineSubsurfaceScattering(hdCamera, renderContext, m_Owner.sssParameters);

                // For opaque forward we have split rendering in two categories
                // Material that are always forward and material that can be deferred or forward depends on render pipeline options (like switch to rendering forward only mode)
                // Material that are always forward are unlit and complex (Like Hair) and don't require sorting, so it is ok to split them.
                RenderForward(cullResults, camera, renderContext, true); // Render deferred or forward opaque
                RenderForwardOnlyOpaque(cullResults, camera, renderContext);

                RenderSky(hdCamera, renderContext);

                // Render all type of transparent forward (unlit, lit, complex (hair...)) to keep the sorting between transparent objects.
                RenderForward(cullResults, camera, renderContext, false);

                RenderVelocity(cullResults, camera, renderContext); // Note we may have to render velocity earlier if we do temporalAO, temporal volumetric etc... Mean we will not take into account forward opaque in case of deferred rendering ?

                // TODO: Check with VFX team.
                // Rendering distortion here have off course lot of artifact.
                // But resolving at each objects that write in distortion is not possible (need to sort transparent, render those that do not distort, then resolve, then etc...)
                // Instead we chose to apply distortion at the end after we cumulate distortion vector and desired blurriness. This
                RenderDistortion(cullResults, camera, renderContext);

                FinalPass(camera, renderContext);
            }

            RenderDebugOverlay(camera, renderContext);

            // bind depth surface for editor grid/gizmo/selection rendering
            if (camera.cameraType == CameraType.SceneView)
            {
                var cmd = new CommandBuffer();
                cmd.SetRenderTarget(BuiltinRenderTextureType.CameraTarget, m_CameraDepthStencilBufferRT);
                renderContext.ExecuteCommandBuffer(cmd);
                cmd.Dispose();
            }

            renderContext.Submit();
        }