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); }); } }
public void UpdateDebugSettings(LightingDebugSettings lightingDebugSettings) { m_LightingDebugSettings = lightingDebugSettings; }
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); }