void InitAndClearBuffer(Camera camera, RenderLoop renderLoop)
        {
            // We clear only the depth buffer, no need to clear the various color buffer as we overwrite them.
            // Clear depth/stencil and init buffers
            {
                var cmd = new CommandBuffer();
                cmd.name = "InitGBuffers and clear Depth/Stencil";

                // Init buffer
                // With scriptable render loop we must allocate ourself depth and color buffer (We must be independent of backbuffer for now, hope to fix that later).
                // Also we manage ourself the HDR format, here allocating fp16 directly.
                // With scriptable render loop we can allocate temporary RT in a command buffer, they will not be release with ExecuteCommandBuffer
                // These temporary surface are release automatically at the end of the scriptable renderloop if not release explicitly
                int w = camera.pixelWidth;
                int h = camera.pixelHeight;

                cmd.GetTemporaryRT(s_CameraColorBuffer, w, h, 0, FilterMode.Point, RenderTextureFormat.ARGBHalf, RenderTextureReadWrite.Default);
                cmd.GetTemporaryRT(s_CameraDepthBuffer, w, h, 24, FilterMode.Point, RenderTextureFormat.Depth);
                m_gbufferManager.InitGBuffers(w, h, cmd);

                cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
                cmd.ClearRenderTarget(true, false, new Color(0, 0, 0, 0));
                renderLoop.ExecuteCommandBuffer(cmd);
                cmd.Dispose();
            }


            // TEMP: As we are in development and have not all the setup pass we still clear the color in emissive buffer and gbuffer, but this will be removed later.

            // Clear HDR target
            {
                var cmd = new CommandBuffer();
                cmd.name = "Clear HDR target";
                cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
                cmd.ClearRenderTarget(false, true, new Color(0, 0, 0, 0));
                renderLoop.ExecuteCommandBuffer(cmd);
                cmd.Dispose();
            }


            // Clear GBuffers
            {
                var cmd = new CommandBuffer();
                cmd.name = "Clear GBuffer";
                // Write into the Camera Depth buffer
                cmd.SetRenderTarget(m_gbufferManager.GetGBuffers(cmd), new RenderTargetIdentifier(s_CameraDepthBuffer));
                // Clear everything
                // TODO: Clear is not required for color as we rewrite everything, will save performance.
                cmd.ClearRenderTarget(false, true, new Color(0, 0, 0, 0));
                renderLoop.ExecuteCommandBuffer(cmd);
                cmd.Dispose();
            }

            // END TEMP
        }
        void RenderDebugViewMaterial(CullResults cull, Camera camera, RenderLoop renderLoop)
        {
            // Render Opaque forward
            {
                var cmd = new CommandBuffer {
                    name = "DebugView Material Mode Pass"
                };
                cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
                cmd.ClearRenderTarget(true, true, new Color(0, 0, 0, 0));
                renderLoop.ExecuteCommandBuffer(cmd);
                cmd.Dispose();

                Shader.SetGlobalInt("_DebugViewMaterial", (int)debugParameters.debugViewMaterial);

                RenderOpaqueRenderList(cull, camera, renderLoop, "DebugViewMaterial");
            }

            // Render GBUffer opaque
            {
                Vector4 screenSize = ComputeScreenSize(camera);
                m_DebugViewMaterialGBuffer.SetVector("_ScreenSize", screenSize);
                m_DebugViewMaterialGBuffer.SetFloat("_DebugViewMaterial", (float)debugParameters.debugViewMaterial);

                // m_gbufferManager.BindBuffers(m_DeferredMaterial);
                // TODO: Bind depth textures
                var cmd = new CommandBuffer {
                    name = "GBuffer Debug Pass"
                };
                cmd.Blit(null, new RenderTargetIdentifier(s_CameraColorBuffer), m_DebugViewMaterialGBuffer, 0);
                renderLoop.ExecuteCommandBuffer(cmd);
                cmd.Dispose();
            }

            // Render forward transparent
            {
                RenderTransparentRenderList(cull, camera, renderLoop, "DebugViewMaterial");
            }

            // Last blit
            {
                var cmd = new CommandBuffer {
                    name = "Blit DebugView Material Debug"
                };
                cmd.Blit(s_CameraColorBuffer, BuiltinRenderTextureType.CameraTarget);
                renderLoop.ExecuteCommandBuffer(cmd);
                cmd.Dispose();
            }
        }
        void FinalPass(RenderLoop renderLoop)
        {
            // Those could be tweakable for the neutral tonemapper, but in the case of the LookDev we don't need that
            const float blackIn       = 0.02f;
            const float whiteIn       = 10.0f;
            const float blackOut      = 0.0f;
            const float whiteOut      = 10.0f;
            const float whiteLevel    = 5.3f;
            const float whiteClip     = 10.0f;
            const float dialUnits     = 20.0f;
            const float halfDialUnits = dialUnits * 0.5f;

            // converting from artist dial units to easy shader-lerps (0-1)
            var tonemapCoeff1 = new Vector4((blackIn * dialUnits) + 1.0f, (blackOut * halfDialUnits) + 1.0f, (whiteIn / dialUnits), (1.0f - (whiteOut / dialUnits)));
            var tonemapCoeff2 = new Vector4(0.0f, 0.0f, whiteLevel, whiteClip / halfDialUnits);

            m_FinalPassMaterial.SetVector("_ToneMapCoeffs1", tonemapCoeff1);
            m_FinalPassMaterial.SetVector("_ToneMapCoeffs2", tonemapCoeff2);

            m_FinalPassMaterial.SetFloat("_EnableToneMap", debugParameters.enableTonemap ? 1.0f : 0.0f);
            m_FinalPassMaterial.SetFloat("_Exposure", debugParameters.exposure);

            var cmd = new CommandBuffer {
                name = "FinalPass"
            };

            // Resolve our HDR texture to CameraTarget.
            cmd.Blit(s_CameraColorBuffer, BuiltinRenderTextureType.CameraTarget, m_FinalPassMaterial, 0);
            renderLoop.ExecuteCommandBuffer(cmd);
            cmd.Dispose();
        }
        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();
        }
예제 #5
0
    public void Draw(RenderLoop loop, Camera camera)
    {
        if (camera.clearFlags != CameraClearFlags.Skybox)
        {
            return;
        }

        var mat = RenderSettings.skybox;

        if (mat == null)
        {
            return;
        }

        var cmd = new CommandBuffer {
            name = "Skybox"
        };

        var looksLikeSixSidedShader = true;

        looksLikeSixSidedShader &= (mat.passCount == 6); // should have six passes
        //looksLikeSixSidedShader &= !mat.GetShader()->GetShaderLabShader()->HasLightingPasses();

        if (looksLikeSixSidedShader)
        {
            Debug.LogWarning("Six sided skybox not yet supported.");
        }
        else
        {
            if (mesh == null)
            {
                CreateMesh();
            }

            var dist = camera.farClipPlane * 10.0f;

            var world = Matrix4x4.TRS(camera.transform.position, Quaternion.identity, new Vector3(dist, dist, dist));

            var skyboxProj = SkyboxHelper.GetProjectionMatrix(camera);
            cmd.SetProjectionAndViewMatrices(skyboxProj, camera.worldToCameraMatrix);
            cmd.DrawMesh(mesh, world, mat);

            cmd.SetProjectionAndViewMatrices(camera.projectionMatrix, camera.worldToCameraMatrix);
        }

        loop.ExecuteCommandBuffer(cmd);
        cmd.Dispose();
    }
        void RenderForwardUnlit(CullResults cullResults, Camera camera, RenderLoop renderLoop)
        {
            // Bind material data
            m_LitRenderLoop.Bind();

            var cmd = new CommandBuffer {
                name = "Forward Unlit Pass"
            };

            cmd.SetRenderTarget(new RenderTargetIdentifier(s_CameraColorBuffer), new RenderTargetIdentifier(s_CameraDepthBuffer));
            renderLoop.ExecuteCommandBuffer(cmd);
            cmd.Dispose();

            RenderOpaqueRenderList(cullResults, camera, renderLoop, "ForwardUnlit");
            RenderTransparentRenderList(cullResults, camera, renderLoop, "ForwardUnlit");
        }
        //---------------------------------------------------------------------------------------------------------------------------------------------------
        private void RenderShadowSplit(ref ShadowSliceData slice, Vector3 lightDirection, Matrix4x4 proj, Matrix4x4 view, ref RenderLoop loop, DrawShadowsSettings settings)
        {
            var commandBuffer = new CommandBuffer {
                name = "ShadowSetup"
            };

            // Set viewport / matrices etc
            commandBuffer.SetViewport(new Rect(slice.atlasX, slice.atlasY, slice.shadowResolution, slice.shadowResolution));
            //commandBuffer.ClearRenderTarget (true, true, Color.green);
            commandBuffer.SetGlobalVector("g_vLightDirWs", new Vector4(lightDirection.x, lightDirection.y, lightDirection.z));
            commandBuffer.SetProjectionAndViewMatrices(proj, view);
            //	commandBuffer.SetGlobalDepthBias (1.0F, 1.0F);
            loop.ExecuteCommandBuffer(commandBuffer);
            commandBuffer.Dispose();

            // Render
            loop.DrawShadows(ref settings);
        }
        void RenderGBuffer(CullResults cull, Camera camera, RenderLoop renderLoop)
        {
            if (debugParameters.useForwardRenderingOnly)
            {
                return;
            }

            // setup GBuffer for rendering
            var cmd = new CommandBuffer {
                name = "GBuffer Pass"
            };

            cmd.SetRenderTarget(m_gbufferManager.GetGBuffers(cmd), new RenderTargetIdentifier(s_CameraDepthBuffer));
            renderLoop.ExecuteCommandBuffer(cmd);
            cmd.Dispose();

            // render opaque objects into GBuffer
            RenderOpaqueRenderList(cull, camera, renderLoop, "GBuffer");
        }
        //---------------------------------------------------------------------------------------------------------------------------------------------------
        // Render shadows
        //---------------------------------------------------------------------------------------------------------------------------------------------------
        void RenderPackedShadows(RenderLoop loop, CullResults cullResults, ref ShadowOutput packedShadows)
        {
            var setRenderTargetCommandBuffer = new CommandBuffer();

            setRenderTargetCommandBuffer.name = "Render packed shadows";
            setRenderTargetCommandBuffer.GetTemporaryRT(m_ShadowTexName, m_Settings.shadowAtlasWidth, m_Settings.shadowAtlasHeight, k_DepthBuffer, FilterMode.Bilinear, RenderTextureFormat.Shadowmap, RenderTextureReadWrite.Linear);
            setRenderTargetCommandBuffer.SetRenderTarget(new RenderTargetIdentifier(m_ShadowTexName));

            setRenderTargetCommandBuffer.ClearRenderTarget(true, true, Color.green);
            loop.ExecuteCommandBuffer(setRenderTargetCommandBuffer);
            setRenderTargetCommandBuffer.Dispose();

            VisibleLight[] visibleLights = cullResults.visibleLights;
            var            shadowSlices  = packedShadows.shadowSlices;

            // Render each light's shadow buffer into a subrect of the shared depth texture
            for (int lightIndex = 0; lightIndex < packedShadows.shadowLights.Length; lightIndex++)
            {
                int shadowSliceCount = packedShadows.shadowLights[lightIndex].shadowSliceCount;
                if (shadowSliceCount == 0)
                {
                    continue;
                }

                Profiler.BeginSample("Shadows.GetShadowCasterBounds");
                Bounds bounds;
                if (!cullResults.GetShadowCasterBounds(lightIndex, out bounds))
                {
                    Profiler.EndSample();
                    return;
                }
                Profiler.EndSample();

                Profiler.BeginSample("Shadows.DrawShadows");

                Matrix4x4 proj;
                Matrix4x4 view;

                var lightType      = visibleLights[lightIndex].lightType;
                var lightDirection = visibleLights[lightIndex].light.transform.forward;
                var shadowNearClip = visibleLights[lightIndex].light.shadowNearPlane;

                int shadowSliceIndex = packedShadows.GetShadowSliceIndex(lightIndex, 0);

                if (lightType == LightType.Spot)
                {
                    var  settings      = new DrawShadowsSettings(cullResults, lightIndex);
                    bool needRendering = cullResults.ComputeSpotShadowsMatricesAndCullingPrimitives(lightIndex, out view, out proj, out settings.splitData);
                    SetupShadowSplitMatrices(ref packedShadows.shadowSlices[shadowSliceIndex], proj, view);
                    if (needRendering)
                    {
                        RenderShadowSplit(ref shadowSlices[shadowSliceIndex], lightDirection, proj, view, ref loop, settings);
                    }
                }
                else if (lightType == LightType.Directional)
                {
                    Vector3 splitRatio = m_Settings.directionalLightCascades;

                    for (int s = 0; s < 4; ++s)
                    {
                        packedShadows.directionalShadowSplitSphereSqr[s] = new Vector4(0, 0, 0, float.NegativeInfinity);
                    }

                    for (int s = 0; s < shadowSliceCount; ++s, shadowSliceIndex++)
                    {
                        var  settings         = new DrawShadowsSettings(cullResults, lightIndex);
                        var  shadowResolution = shadowSlices[shadowSliceIndex].shadowResolution;
                        bool needRendering    = cullResults.ComputeDirectionalShadowMatricesAndCullingPrimitives(lightIndex, s, shadowSliceCount, splitRatio, shadowResolution, shadowNearClip, out view, out proj, out settings.splitData);

                        packedShadows.directionalShadowSplitSphereSqr[s]    = settings.splitData.cullingSphere;
                        packedShadows.directionalShadowSplitSphereSqr[s].w *= packedShadows.directionalShadowSplitSphereSqr[s].w;

                        SetupShadowSplitMatrices(ref shadowSlices[shadowSliceIndex], proj, view);
                        if (needRendering)
                        {
                            RenderShadowSplit(ref shadowSlices[shadowSliceIndex], lightDirection, proj, view, ref loop, settings);
                        }
                    }
                }
                else if (lightType == LightType.Point)
                {
                    for (int s = 0; s < shadowSliceCount; ++s, shadowSliceIndex++)
                    {
                        var  settings      = new DrawShadowsSettings(cullResults, lightIndex);
                        bool needRendering = cullResults.ComputePointShadowsMatricesAndCullingPrimitives(lightIndex, (CubemapFace)s, 2.0f, out view, out proj, out settings.splitData);

                        SetupShadowSplitMatrices(ref shadowSlices[shadowSliceIndex], proj, view);
                        if (needRendering)
                        {
                            RenderShadowSplit(ref shadowSlices[shadowSliceIndex], lightDirection, proj, view, ref loop, settings);
                        }
                    }
                }
                Profiler.EndSample();
            }
        }