Example #1
0
        public void RenderLightVolumes(RenderGraph renderGraph, LightingDebugSettings lightingDebugSettings, TextureHandle destination, TextureHandle depthBuffer, CullingResults cullResults, HDCamera hdCamera)
        {
            using (var builder = renderGraph.AddRenderPass <RenderLightVolumesPassData>("LightVolumes", out var passData))
            {
                bool lightOverlapEnabled = CoreUtils.IsLightOverlapDebugEnabled(hdCamera.camera);
                bool useColorAndEdge     = lightingDebugSettings.lightVolumeDebugByCategory == LightVolumeDebug.ColorAndEdge || lightOverlapEnabled;

                passData.hdCamera    = hdCamera;
                passData.cullResults = cullResults;
                passData.debugLightVolumeMaterial = m_DebugLightVolumeMaterial;
                passData.debugLightVolumeCS       = m_DebugLightVolumeCompute;
                passData.debugLightVolumeKernel   = useColorAndEdge ? m_DebugLightVolumeColorsKernel : m_DebugLightVolumeGradientKernel;
                passData.maxDebugLightCount       = (int)lightingDebugSettings.maxDebugLightCount;
                passData.borderRadius             = lightOverlapEnabled ? 0.5f : 1f;
                passData.colorGradientTexture     = m_ColorGradientTexture;
                passData.lightOverlapEnabled      = lightOverlapEnabled;
                passData.lightCountBuffer         = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R32_SFloat, clearBuffer = true, clearColor = Color.black, name = "LightVolumeCount"
                });
                passData.colorAccumulationBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.black, name = "LightVolumeColorAccumulation"
                });
                passData.debugLightVolumesTexture = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
                {
                    colorFormat = GraphicsFormat.R16G16B16A16_SFloat, clearBuffer = true, clearColor = Color.black, enableRandomWrite = true, name = "LightVolumeDebugLightVolumesTexture"
                });
                passData.depthBuffer = builder.UseDepthBuffer(depthBuffer, DepthAccess.ReadWrite);
                passData.destination = builder.WriteTexture(destination);

                builder.SetRenderFunc(
                    (RenderLightVolumesPassData data, RenderGraphContext ctx) =>
                {
                    var mpb = ctx.renderGraphPool.GetTempMaterialPropertyBlock();
                    RenderTargetIdentifier[] mrt = ctx.renderGraphPool.GetTempArray <RenderTargetIdentifier>(2);
                    mrt[0] = data.lightCountBuffer;
                    mrt[1] = data.colorAccumulationBuffer;

                    if (data.lightOverlapEnabled)
                    {
                        // We only need the accumulation buffer, not the color (we only display the outline of the light shape in this mode).
                        CoreUtils.SetRenderTarget(ctx.cmd, mrt[0], depthBuffer);

                        // The cull result doesn't contains overlapping lights so we use a custom list
                        foreach (var overlappingHDLight in HDAdditionalLightData.s_overlappingHDLights)
                        {
                            RenderLightVolume(ctx.cmd, data.debugLightVolumeMaterial, overlappingHDLight, overlappingHDLight.legacyLight, mpb);
                        }
                    }
                    else
                    {
                        // Set the render target array
                        CoreUtils.SetRenderTarget(ctx.cmd, mrt, depthBuffer);

                        // First of all let's do the regions for the light sources (we only support Punctual and Area)
                        int numLights = data.cullResults.visibleLights.Length;
                        for (int lightIdx = 0; lightIdx < numLights; ++lightIdx)
                        {
                            // Let's build the light's bounding sphere matrix
                            Light currentLegacyLight = data.cullResults.visibleLights[lightIdx].light;
                            if (currentLegacyLight == null)
                            {
                                continue;
                            }
                            HDAdditionalLightData currentHDRLight = currentLegacyLight.GetComponent <HDAdditionalLightData>();
                            if (currentHDRLight == null)
                            {
                                continue;
                            }

                            RenderLightVolume(ctx.cmd, data.debugLightVolumeMaterial, currentHDRLight, currentLegacyLight, mpb);
                        }

                        // When we enable the light overlap mode we hide probes as they can't be baked in shadow masks
                        if (!data.lightOverlapEnabled)
                        {
                            // Now let's do the same but for reflection probes
                            int numProbes = data.cullResults.visibleReflectionProbes.Length;
                            for (int probeIdx = 0; probeIdx < numProbes; ++probeIdx)
                            {
                                // Let's build the light's bounding sphere matrix
                                ReflectionProbe currentLegacyProbe        = data.cullResults.visibleReflectionProbes[probeIdx].reflectionProbe;
                                HDAdditionalReflectionData currentHDProbe = currentLegacyProbe.GetComponent <HDAdditionalReflectionData>();

                                if (!currentHDProbe)
                                {
                                    continue;
                                }

                                MaterialPropertyBlock m_MaterialProperty = new MaterialPropertyBlock();
                                Mesh targetMesh = null;
                                if (currentHDProbe.influenceVolume.shape == InfluenceShape.Sphere)
                                {
                                    m_MaterialProperty.SetVector(_RangeShaderID, new Vector3(currentHDProbe.influenceVolume.sphereRadius, currentHDProbe.influenceVolume.sphereRadius, currentHDProbe.influenceVolume.sphereRadius));
                                    targetMesh = DebugShapes.instance.RequestSphereMesh();
                                }
                                else
                                {
                                    m_MaterialProperty.SetVector(_RangeShaderID, new Vector3(currentHDProbe.influenceVolume.boxSize.x, currentHDProbe.influenceVolume.boxSize.y, currentHDProbe.influenceVolume.boxSize.z));
                                    targetMesh = DebugShapes.instance.RequestBoxMesh();
                                }

                                m_MaterialProperty.SetColor(_ColorShaderID, new Color(1.0f, 1.0f, 0.0f, 1.0f));
                                m_MaterialProperty.SetVector(_OffsetShaderID, new Vector3(0, 0, 0));
                                Matrix4x4 positionMat = Matrix4x4.Translate(currentLegacyProbe.transform.position);
                                ctx.cmd.DrawMesh(targetMesh, positionMat, data.debugLightVolumeMaterial, 0, 0, m_MaterialProperty);
                            }
                        }
                    }

                    // Set the input params for the compute
                    ctx.cmd.SetComputeTextureParam(data.debugLightVolumeCS, data.debugLightVolumeKernel, _DebugLightCountBufferShaderID, data.lightCountBuffer);
                    ctx.cmd.SetComputeTextureParam(data.debugLightVolumeCS, data.debugLightVolumeKernel, _DebugColorAccumulationBufferShaderID, data.colorAccumulationBuffer);
                    ctx.cmd.SetComputeTextureParam(data.debugLightVolumeCS, data.debugLightVolumeKernel, _DebugLightVolumesTextureShaderID, data.debugLightVolumesTexture);
                    ctx.cmd.SetComputeTextureParam(data.debugLightVolumeCS, data.debugLightVolumeKernel, _ColorGradientTextureShaderID, data.colorGradientTexture);
                    ctx.cmd.SetComputeIntParam(data.debugLightVolumeCS, _MaxDebugLightCountShaderID, data.maxDebugLightCount);
                    ctx.cmd.SetComputeFloatParam(data.debugLightVolumeCS, _BorderRadiusShaderID, data.borderRadius);

                    // Texture dimensions
                    int texWidth  = data.hdCamera.actualWidth;
                    int texHeight = data.hdCamera.actualHeight;

                    // Dispatch the compute
                    int lightVolumesTileSize = 8;
                    int numTilesX            = (texWidth + (lightVolumesTileSize - 1)) / lightVolumesTileSize;
                    int numTilesY            = (texHeight + (lightVolumesTileSize - 1)) / lightVolumesTileSize;
                    ctx.cmd.DispatchCompute(data.debugLightVolumeCS, data.debugLightVolumeKernel, numTilesX, numTilesY, data.hdCamera.viewCount);

                    // Blit this into the camera target
                    CoreUtils.SetRenderTarget(ctx.cmd, destination);
                    mpb.SetTexture(HDShaderIDs._BlitTexture, data.debugLightVolumesTexture);
                    ctx.cmd.DrawProcedural(Matrix4x4.identity, data.debugLightVolumeMaterial, 1, MeshTopology.Triangles, 3, 1, mpb);
                });
            }
        }
Example #2
0
 public void UpdateDebugSettings(LightingDebugSettings lightingDebugSettings)
 {
     m_LightingDebugSettings = lightingDebugSettings;
 }
Example #3
0
        public RenderLightVolumesParameters PrepareLightVolumeParameters(HDCamera hdCamera, LightingDebugSettings lightDebugSettings, CullingResults cullResults)
        {
            var parameters = new RenderLightVolumesParameters();

            parameters.hdCamera    = hdCamera;
            parameters.cullResults = cullResults;
            parameters.debugLightVolumeMaterial = m_DebugLightVolumeMaterial;
            parameters.debugLightVolumeCS       = m_DebugLightVolumeCompute;
            parameters.debugLightVolumeKernel   = lightDebugSettings.lightVolumeDebugByCategory == LightVolumeDebug.ColorAndEdge ? m_DebugLightVolumeColorsKernel : m_DebugLightVolumeGradientKernel;
            parameters.maxDebugLightCount       = (int)lightDebugSettings.maxDebugLightCount;
            parameters.colorGradientTexture     = m_ColorGradientTexture;

            return(parameters);
        }