// This functions returns a mask that tells us for a given slot and based on the light type, which channels should hold the shadow information. static void GetShadowChannelMask(int shadowSlot, ScreenSpaceShadowType shadowType, ref Vector4 outputMask) { int outputChannel = shadowSlot % 4; if (shadowType == ScreenSpaceShadowType.GrayScale) { switch (outputChannel) { case 0: { outputMask.Set(1.0f, 0.0f, 0.0f, 0.0f); break; } case 1: { outputMask.Set(0.0f, 1.0f, 0.0f, 0.0f); break; } case 2: { outputMask.Set(0.0f, 0.0f, 1.0f, 0.0f); break; } case 3: { outputMask.Set(0.0f, 0.0f, 0.0f, 1.0f); break; } } } else if (shadowType == ScreenSpaceShadowType.Area) { switch (outputChannel) { case 0: { outputMask.Set(1.0f, 1.0f, 0.0f, 0.0f); break; } case 1: { outputMask.Set(0.0f, 1.0f, 1.0f, 0.0f); break; } case 2: { outputMask.Set(0.0f, 0.0f, 1.0f, 1.0f); break; } default: Debug.Assert(false); break; } } else if (shadowType == ScreenSpaceShadowType.Color) { switch (outputChannel) { case 0: { outputMask.Set(1.0f, 1.0f, 1.0f, 0.0f); break; } default: Debug.Assert(false); break; } } }
void WriteScreenSpaceShadow(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle shadowTexture, TextureHandle screenSpaceShadowArray, int shadowIndex, ScreenSpaceShadowType shadowType) { // Write the result texture to the screen space shadow buffer using (var builder = renderGraph.AddRenderPass <WriteScreenSpaceShadowPassData>("Write Screen Space Shadows", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingWriteShadow))) { passData.texWidth = hdCamera.actualWidth; passData.texHeight = hdCamera.actualHeight; passData.viewCount = hdCamera.viewCount; // Evaluation parameters GetShadowChannelMask(shadowIndex, shadowType, ref passData.shadowChannelMask); // If the light is an area, we also need to grab the individual channels if (shadowType == ScreenSpaceShadowType.Area) { GetShadowChannelMask(shadowIndex, ScreenSpaceShadowType.GrayScale, ref passData.shadowChannelMask0); GetShadowChannelMask(shadowIndex + 1, ScreenSpaceShadowType.GrayScale, ref passData.shadowChannelMask1); } passData.shadowSlot = shadowIndex; // Kernel switch (shadowType) { case ScreenSpaceShadowType.GrayScale: { passData.shadowKernel = m_OutputShadowTextureKernel; } break; case ScreenSpaceShadowType.Area: { passData.shadowKernel = m_OutputSpecularShadowTextureKernel; } break; case ScreenSpaceShadowType.Color: { passData.shadowKernel = m_OutputColorShadowTextureKernel; } break; } // Other parameters passData.screenSpaceShadowCS = m_ScreenSpaceShadowsCS; passData.inputShadowBuffer = builder.ReadTexture(shadowTexture); passData.outputShadowArrayBuffer = builder.ReadWriteTexture(screenSpaceShadowArray); builder.SetRenderFunc( (WriteScreenSpaceShadowPassData data, RenderGraphContext ctx) => { // Evaluate the dispatch parameters int shadowTileSize = 8; int numTilesX = (data.texWidth + (shadowTileSize - 1)) / shadowTileSize; int numTilesY = (data.texHeight + (shadowTileSize - 1)) / shadowTileSize; // Bind the input data ctx.cmd.SetComputeIntParam(data.screenSpaceShadowCS, HDShaderIDs._RaytracingShadowSlot, data.shadowSlot / 4); ctx.cmd.SetComputeVectorParam(data.screenSpaceShadowCS, HDShaderIDs._RaytracingChannelMask, data.shadowChannelMask); ctx.cmd.SetComputeVectorParam(data.screenSpaceShadowCS, HDShaderIDs._RaytracingChannelMask0, data.shadowChannelMask0); ctx.cmd.SetComputeVectorParam(data.screenSpaceShadowCS, HDShaderIDs._RaytracingChannelMask1, data.shadowChannelMask1); ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.shadowKernel, HDShaderIDs._RaytracedShadowIntegration, data.inputShadowBuffer); // Bind the output texture ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.shadowKernel, HDShaderIDs._ScreenSpaceShadowsTextureRW, data.outputShadowArrayBuffer); //Do our copy ctx.cmd.DispatchCompute(data.screenSpaceShadowCS, data.shadowKernel, numTilesX, numTilesY, data.viewCount); }); } }
void RenderRayTracedDirectionalScreenSpaceShadow(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle depthBuffer, TextureHandle normalBuffer, TextureHandle motionVetorsBuffer, TextureHandle rayCountTexture, TextureHandle screenSpaceShadowArray) { TextureHandle directionalShadow; TextureHandle velocityBuffer; TextureHandle distanceBuffer; RTShadowDirectionalTraceParameters rtsdtParams = PrepareRTShadowDirectionalTraceParameters(hdCamera, m_CurrentSunLightAdditionalLightData); using (var builder = renderGraph.AddRenderPass <RTSDirectionalTracePassData>("Directional RT Shadow", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingDirectionalLightShadow))) { passData.parameters = rtsdtParams; // Input Buffer passData.depthStencilBuffer = builder.UseDepthBuffer(depthBuffer, DepthAccess.Read); passData.normalBuffer = builder.ReadTexture(normalBuffer); passData.directionBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Direction Buffer" }); // Debug buffers passData.rayCountTexture = builder.ReadTexture(builder.WriteTexture(rayCountTexture)); // Output Buffers passData.velocityBuffer = builder.ReadTexture(builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R8_SNorm, enableRandomWrite = true, clearBuffer = true, name = "Velocity Buffer" }))); passData.distanceBuffer = builder.ReadTexture(builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R32_SFloat, enableRandomWrite = true, clearBuffer = true, name = "Distance Buffer" }))); passData.outputShadowBuffer = builder.ReadTexture(builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, clearBuffer = true, name = "RT Directional Shadow" }))); builder.SetRenderFunc( (RTSDirectionalTracePassData data, RenderGraphContext context) => { RTShadowDirectionalTraceResources resources = new RTShadowDirectionalTraceResources(); resources.depthStencilBuffer = data.depthStencilBuffer; resources.normalBuffer = data.normalBuffer; resources.directionBuffer = data.directionBuffer; resources.rayCountTexture = data.rayCountTexture; resources.velocityBuffer = data.velocityBuffer; resources.distanceBuffer = data.distanceBuffer; resources.outputShadowBuffer = data.outputShadowBuffer; ExecuteSSSDirectionalTrace(context.cmd, data.parameters, resources); }); directionalShadow = passData.outputShadowBuffer; velocityBuffer = passData.velocityBuffer; distanceBuffer = passData.distanceBuffer; } // If required, denoise the shadow if (m_CurrentSunLightAdditionalLightData.filterTracedShadow && rtsdtParams.softShadow) { directionalShadow = DenoiseDirectionalScreenSpaceShadow(renderGraph, hdCamera, depthBuffer, normalBuffer, motionVetorsBuffer, directionalShadow, velocityBuffer, distanceBuffer); } int dirShadowIndex = m_CurrentSunLightDirectionalLightData.screenSpaceShadowIndex & (int)LightDefinitions.s_ScreenSpaceShadowIndexMask; ScreenSpaceShadowType shadowType = m_CurrentSunLightAdditionalLightData.colorShadow? ScreenSpaceShadowType.Color: ScreenSpaceShadowType.GrayScale; // Write the result texture to the screen space shadow buffer WriteScreenSpaceShadow(renderGraph, hdCamera, directionalShadow, screenSpaceShadowArray, dirShadowIndex, shadowType); }
WriteScreenSpaceShadowParameters PrepareWriteScreenSpaceShadowParameters(HDCamera hdCamera, int shadowSlot, ScreenSpaceShadowType shadowType) { WriteScreenSpaceShadowParameters wsssParams = new WriteScreenSpaceShadowParameters(); // Set the camera parameters wsssParams.texWidth = hdCamera.actualWidth; wsssParams.texHeight = hdCamera.actualHeight; wsssParams.viewCount = hdCamera.viewCount; // Evaluation parameters GetShadowChannelMask(shadowSlot, shadowType, ref wsssParams.shadowChannelMask); // If the light is an area, we also need to grab the individual channels if (shadowType == ScreenSpaceShadowType.Area) { GetShadowChannelMask(shadowSlot, ScreenSpaceShadowType.GrayScale, ref wsssParams.shadowChannelMask0); GetShadowChannelMask(shadowSlot + 1, ScreenSpaceShadowType.GrayScale, ref wsssParams.shadowChannelMask1); } wsssParams.shadowSlot = shadowSlot; // Kernel switch (shadowType) { case ScreenSpaceShadowType.GrayScale: { wsssParams.shadowKernel = m_OutputShadowTextureKernel; } break; case ScreenSpaceShadowType.Area: { wsssParams.shadowKernel = m_OutputSpecularShadowTextureKernel; } break; case ScreenSpaceShadowType.Color: { wsssParams.shadowKernel = m_OutputColorShadowTextureKernel; } break; } // Other parameters wsssParams.screenSpaceShadowCS = m_ScreenSpaceShadowsCS; return(wsssParams); }
void WriteScreenSpaceShadow(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle shadowTexture, TextureHandle screenSpaceShadowArray, int shadowIndex, ScreenSpaceShadowType shadowType) { // Write the result texture to the screen space shadow buffer using (var builder = renderGraph.AddRenderPass <WriteScreenSpaceShadowPassData>("Write Screen Space Shadows", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingWriteShadow))) { passData.parameters = PrepareWriteScreenSpaceShadowParameters(hdCamera, shadowIndex, shadowType); passData.inputShadowBuffer = builder.ReadTexture(shadowTexture); passData.outputShadowArrayBuffer = builder.WriteTexture(builder.ReadTexture(screenSpaceShadowArray)); builder.SetRenderFunc( (WriteScreenSpaceShadowPassData data, RenderGraphContext context) => { WriteScreenSpaceShadowResources resources = new WriteScreenSpaceShadowResources(); resources.inputShadowBuffer = data.inputShadowBuffer; resources.outputShadowArrayBuffer = data.outputShadowArrayBuffer; ExecuteWriteScreenSpaceShadow(context.cmd, data.parameters, resources); }); } }
WriteScreenSpaceShadowParameters PrepareWriteScreenSpaceShadowParameters(HDCamera hdCamera, int shadowSlot, ScreenSpaceShadowType shadowType) { WriteScreenSpaceShadowParameters wsssParams = new WriteScreenSpaceShadowParameters(); // Set the camera parameters wsssParams.texWidth = hdCamera.actualWidth; wsssParams.texHeight = hdCamera.actualHeight; wsssParams.viewCount = hdCamera.viewCount; // Evaluation parameters GetShadowChannelMask(shadowSlot, shadowType, ref wsssParams.shadowChannelMask); wsssParams.shadowSlot = shadowSlot; // Kernel wsssParams.shadowKernel = (shadowType == ScreenSpaceShadowType.Color ? m_OutputColorShadowTextureKernel : m_OutputShadowTextureKernel); // Other parameters wsssParams.screenSpaceShadowCS = m_ScreenSpaceShadowsCS; return(wsssParams); }
void RenderRayTracedDirectionalScreenSpaceShadow(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle depthBuffer, TextureHandle normalBuffer, TextureHandle motionVetorsBuffer, TextureHandle historyValidityBuffer, TextureHandle rayCountTexture, TextureHandle screenSpaceShadowArray) { TextureHandle directionalShadow; TextureHandle velocityBuffer; TextureHandle distanceBuffer; bool softShadows = m_CurrentSunLightAdditionalLightData.angularDiameter > 0.0 ? true : false; using (var builder = renderGraph.AddRenderPass <RTSDirectionalTracePassData>("Directional RT Shadow", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingDirectionalLightShadow))) { RayTracingSettings rayTracingSettings = hdCamera.volumeStack.GetComponent <RayTracingSettings>(); // Set the camera parameters passData.texWidth = hdCamera.actualWidth; passData.texHeight = hdCamera.actualHeight; passData.viewCount = hdCamera.viewCount; // Evaluation parameters passData.softShadow = softShadows; // If the surface is infinitively small, we force it to one sample. passData.numShadowSamples = passData.softShadow ? m_CurrentSunLightAdditionalLightData.numRayTracingSamples : 1; passData.colorShadow = m_CurrentSunLightAdditionalLightData.colorShadow; passData.maxShadowLength = rayTracingSettings.directionalShadowRayLength.value; // Kernels passData.clearShadowKernel = m_ClearShadowTexture; passData.directionalShadowSample = m_RaytracingDirectionalShadowSample; // Grab the acceleration structure for the target camera passData.accelerationStructure = RequestAccelerationStructure(hdCamera); passData.screenSpaceShadowCS = m_ScreenSpaceShadowsCS; passData.screenSpaceShadowRT = m_ScreenSpaceShadowsRT; passData.shaderVariablesRayTracingCB = m_ShaderVariablesRayTracingCB; passData.ditheredTextureSet = GetBlueNoiseManager().DitheredTextureSet8SPP(); // Input Buffer passData.depthStencilBuffer = builder.UseDepthBuffer(depthBuffer, DepthAccess.Read); passData.normalBuffer = builder.ReadTexture(normalBuffer); passData.directionBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Direction Buffer" }); // Debug buffers passData.rayCountTexture = builder.ReadWriteTexture(rayCountTexture); // Output Buffers passData.velocityBuffer = builder.ReadWriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R8_SNorm, enableRandomWrite = true, clearBuffer = true, name = "Velocity Buffer" })); passData.distanceBuffer = builder.ReadWriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R32_SFloat, enableRandomWrite = true, clearBuffer = true, name = "Distance Buffer" })); passData.outputShadowBuffer = builder.ReadWriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, clearBuffer = true, name = "RT Directional Shadow" })); builder.SetRenderFunc( (RTSDirectionalTracePassData data, RenderGraphContext ctx) => { // Inject the ray-tracing sampling data BlueNoise.BindDitheredTextureSet(ctx.cmd, data.ditheredTextureSet); // Evaluate the dispatch parameters int shadowTileSize = 8; int numTilesX = (data.texWidth + (shadowTileSize - 1)) / shadowTileSize; int numTilesY = (data.texHeight + (shadowTileSize - 1)) / shadowTileSize; // Clear the integration texture ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.clearShadowKernel, HDShaderIDs._RaytracedShadowIntegration, data.outputShadowBuffer); ctx.cmd.DispatchCompute(data.screenSpaceShadowCS, data.clearShadowKernel, numTilesX, numTilesY, data.viewCount); ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.clearShadowKernel, HDShaderIDs._RaytracedShadowIntegration, data.velocityBuffer); ctx.cmd.DispatchCompute(data.screenSpaceShadowCS, data.clearShadowKernel, numTilesX, numTilesY, data.viewCount); ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.clearShadowKernel, HDShaderIDs._RaytracedShadowIntegration, data.distanceBuffer); ctx.cmd.DispatchCompute(data.screenSpaceShadowCS, data.clearShadowKernel, numTilesX, numTilesY, data.viewCount); // Grab and bind the acceleration structure for the target camera ctx.cmd.SetRayTracingAccelerationStructure(data.screenSpaceShadowRT, HDShaderIDs._RaytracingAccelerationStructureName, data.accelerationStructure); // Make sure the right closest hit/any hit will be triggered by using the right multi compile CoreUtils.SetKeyword(ctx.cmd, "TRANSPARENT_COLOR_SHADOW", data.colorShadow); // Define which ray generation shaders we shall be using string directionaLightShadowShader = data.colorShadow ? m_RayGenDirectionalColorShadowSingleName : m_RayGenDirectionalShadowSingleName; // Loop through the samples of this frame for (int sampleIdx = 0; sampleIdx < data.numShadowSamples; ++sampleIdx) { // Update global Constant Buffer data.shaderVariablesRayTracingCB._RaytracingSampleIndex = sampleIdx; data.shaderVariablesRayTracingCB._RaytracingNumSamples = data.numShadowSamples; ConstantBuffer.PushGlobal(ctx.cmd, data.shaderVariablesRayTracingCB, HDShaderIDs._ShaderVariablesRaytracing); // Input Buffer ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.directionalShadowSample, HDShaderIDs._DepthTexture, data.depthStencilBuffer); ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.directionalShadowSample, HDShaderIDs._NormalBufferTexture, data.normalBuffer); // Output buffer ctx.cmd.SetComputeTextureParam(data.screenSpaceShadowCS, data.directionalShadowSample, HDShaderIDs._RaytracingDirectionBuffer, data.directionBuffer); // Generate a new direction ctx.cmd.DispatchCompute(data.screenSpaceShadowCS, data.directionalShadowSample, numTilesX, numTilesY, data.viewCount); // Define the shader pass to use for the shadow pass ctx.cmd.SetRayTracingShaderPass(data.screenSpaceShadowRT, "VisibilityDXR"); // Input Uniforms ctx.cmd.SetRayTracingFloatParam(data.screenSpaceShadowRT, HDShaderIDs._DirectionalMaxRayLength, data.maxShadowLength); // Set ray count texture ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, HDShaderIDs._RayCountTexture, data.rayCountTexture); // Input buffers ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, HDShaderIDs._DepthTexture, data.depthStencilBuffer); ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, HDShaderIDs._NormalBufferTexture, data.normalBuffer); ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, HDShaderIDs._RaytracingDirectionBuffer, data.directionBuffer); // Output buffer ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, data.colorShadow ? HDShaderIDs._RaytracedColorShadowIntegration : HDShaderIDs._RaytracedShadowIntegration, data.outputShadowBuffer); ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, HDShaderIDs._VelocityBuffer, data.velocityBuffer); ctx.cmd.SetRayTracingTextureParam(data.screenSpaceShadowRT, HDShaderIDs._RaytracingDistanceBufferRW, data.distanceBuffer); // Evaluate the visibility ctx.cmd.DispatchRays(data.screenSpaceShadowRT, directionaLightShadowShader, (uint)data.texWidth, (uint)data.texHeight, (uint)data.viewCount); } // Now that we are done with the ray tracing bit, disable the multi compile that was potentially enabled CoreUtils.SetKeyword(ctx.cmd, "TRANSPARENT_COLOR_SHADOW", false); }); directionalShadow = passData.outputShadowBuffer; velocityBuffer = passData.velocityBuffer; distanceBuffer = passData.distanceBuffer; } // If required, denoise the shadow if (m_CurrentSunLightAdditionalLightData.filterTracedShadow && softShadows) { directionalShadow = DenoiseDirectionalScreenSpaceShadow(renderGraph, hdCamera, depthBuffer, normalBuffer, motionVetorsBuffer, historyValidityBuffer, directionalShadow, velocityBuffer, distanceBuffer); } int dirShadowIndex = m_CurrentSunLightDirectionalLightData.screenSpaceShadowIndex & (int)LightDefinitions.s_ScreenSpaceShadowIndexMask; ScreenSpaceShadowType shadowType = m_CurrentSunLightAdditionalLightData.colorShadow ? ScreenSpaceShadowType.Color : ScreenSpaceShadowType.GrayScale; // Write the result texture to the screen space shadow buffer WriteScreenSpaceShadow(renderGraph, hdCamera, directionalShadow, screenSpaceShadowArray, dirShadowIndex, shadowType); }