TextureHandle TraceRTSSS(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle depthStencilBuffer, TextureHandle normalBuffer, TextureHandle sssColor, TextureHandle ssgiBuffer, TextureHandle diffuseLightingBuffer, TextureHandle colorBuffer) { using (var builder = renderGraph.AddRenderPass <TraceRTSSSPassData>("Composing the result of RTSSS", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingSSSTrace))) { builder.EnableAsyncCompute(false); // Grab the SSS params var settings = hdCamera.volumeStack.GetComponent <SubSurfaceScattering>(); passData.parameters = PrepareSSSRayTracingParameters(hdCamera, settings); passData.depthStencilBuffer = builder.UseDepthBuffer(depthStencilBuffer, DepthAccess.Read); passData.normalBuffer = builder.ReadTexture(normalBuffer); passData.sssColor = builder.ReadTexture(sssColor); passData.intermediateBuffer0 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Intermediate Texture 0" }); passData.intermediateBuffer1 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Intermediate Texture 1" }); passData.intermediateBuffer2 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Intermediate Texture 2" }); passData.intermediateBuffer3 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Intermediate Texture 3" }); passData.directionBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Distance buffer" }); passData.outputBuffer = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Ray Traced SSS" })); builder.SetRenderFunc( (TraceRTSSSPassData data, RenderGraphContext ctx) => { // We need to fill the structure that holds the various resources SSSRayTracingResources ssstResources = new SSSRayTracingResources(); ssstResources.depthStencilBuffer = data.depthStencilBuffer; ssstResources.normalBuffer = data.normalBuffer; ssstResources.sssColor = data.sssColor; ssstResources.intermediateBuffer0 = data.intermediateBuffer0; ssstResources.intermediateBuffer1 = data.intermediateBuffer1; ssstResources.intermediateBuffer2 = data.intermediateBuffer2; ssstResources.intermediateBuffer3 = data.intermediateBuffer3; ssstResources.directionBuffer = data.directionBuffer; ssstResources.outputBuffer = data.outputBuffer; ExecuteRTSubsurfaceScattering(ctx.cmd, data.parameters, ssstResources); }); return(passData.outputBuffer); } }
void RenderSubsurfaceScatteringRT(HDCamera hdCamera, CommandBuffer cmd, RTHandle colorBufferRT, RTHandle diffuseBufferRT, RTHandle depthStencilBufferRT, RTHandle depthTextureRT) { using (new ProfilingScope(cmd, ProfilingSampler.Get(HDProfileId.SubsurfaceScattering))) { // Grab the SSS params var settings = hdCamera.volumeStack.GetComponent <SubSurfaceScattering>(); // Fetch all the intermediate buffers that we need (too much of them to be fair) RTHandle intermediateBuffer0 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA0); RTHandle intermediateBuffer1 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA1); RTHandle intermediateBuffer2 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA2); RTHandle intermediateBuffer3 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA3); RTHandle intermediateBuffer4 = GetRayTracingBuffer(InternalRayTracingBuffers.RGBA4); RTHandle directionBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.Direction); // Evaluate the lighting for the samples that we need to SSSRayTracingParameters sssrtParams = PrepareSSSRayTracingParameters(hdCamera, settings); SSSRayTracingResources sssrtResources = PrepareSSSRayTracingResources(m_SSSColor, intermediateBuffer0, intermediateBuffer1, intermediateBuffer2, intermediateBuffer3, directionBuffer, intermediateBuffer4); ExecuteRTSubsurfaceScattering(cmd, sssrtParams, sssrtResources); // Grab the history buffer RTHandle subsurfaceHistory = hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RayTracedSubSurface) ?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RayTracedSubSurface, SubSurfaceHistoryBufferAllocatorFunction, 1); // Check if we need to invalidate the history float historyValidity = EvaluateHistoryValidity(hdCamera); // Apply temporal filtering to the signal HDTemporalFilter temporalFilter = GetTemporalFilter(); TemporalFilterParameters tfParameters = temporalFilter.PrepareTemporalFilterParameters(hdCamera, false, historyValidity); RTHandle validationBuffer = GetRayTracingBuffer(InternalRayTracingBuffers.R0); TemporalFilterResources tfResources = temporalFilter.PrepareTemporalFilterResources(hdCamera, validationBuffer, intermediateBuffer4, subsurfaceHistory, intermediateBuffer0); HDTemporalFilter.DenoiseBuffer(cmd, tfParameters, tfResources); // Combine the result with the rest of the lighting SSSCombineParameters ssscParams = PrepareSSSCombineParameters(hdCamera); SSSCombineResources ssscResources = PrepareSSSCombineResources(m_SSSColor, colorBufferRT, diffuseBufferRT, intermediateBuffer0, ssscParams.validSSGI); ExecuteCombineSubsurfaceScattering(cmd, ssscParams, ssscResources); // Push this version of the texture for debug PushFullScreenDebugTexture(hdCamera, cmd, diffuseBufferRT, FullScreenDebugMode.RayTracedSubSurface); } }
SSSRayTracingResources PrepareSSSRayTracingResources(RTHandle sssColor, RTHandle intermediateBuffer0, RTHandle intermediateBuffer1, RTHandle intermediateBuffer2, RTHandle intermediateBuffer3, RTHandle directionBuffer, RTHandle outputBuffer) { SSSRayTracingResources sssrtResources = new SSSRayTracingResources(); // Input buffers sssrtResources.depthStencilBuffer = sharedRTManager.GetDepthStencilBuffer(); sssrtResources.normalBuffer = sharedRTManager.GetNormalBuffer(); sssrtResources.sssColor = sssColor; // Intermediate buffers sssrtResources.intermediateBuffer0 = intermediateBuffer0; sssrtResources.intermediateBuffer1 = intermediateBuffer1; sssrtResources.intermediateBuffer2 = intermediateBuffer2; sssrtResources.intermediateBuffer3 = intermediateBuffer3; sssrtResources.directionBuffer = directionBuffer; // Output Buffers sssrtResources.outputBuffer = outputBuffer; return(sssrtResources); }
static void ExecuteRTSubsurfaceScattering(CommandBuffer cmd, SSSRayTracingParameters sssrtParams, SSSRayTracingResources sssrtResources) { // Evaluate the dispatch parameters int numTilesXHR = (sssrtParams.texWidth + (s_sssTileSize - 1)) / s_sssTileSize; int numTilesYHR = (sssrtParams.texHeight + (s_sssTileSize - 1)) / s_sssTileSize; // Clear the integration texture first cmd.SetComputeTextureParam(sssrtParams.rayTracingSubSurfaceCS, sssrtParams.clearTextureKernel, HDShaderIDs._DiffuseLightingTextureRW, sssrtResources.outputBuffer); cmd.DispatchCompute(sssrtParams.rayTracingSubSurfaceCS, sssrtParams.clearTextureKernel, numTilesXHR, numTilesYHR, sssrtParams.viewCount); // Define the shader pass to use for the reflection pass cmd.SetRayTracingShaderPass(sssrtParams.rayTracingSubSurfaceRT, "SubSurfaceDXR"); // Set the acceleration structure for the pass cmd.SetRayTracingAccelerationStructure(sssrtParams.rayTracingSubSurfaceRT, HDShaderIDs._RaytracingAccelerationStructureName, sssrtParams.accelerationStructure); // Inject the ray-tracing sampling data BlueNoise.BindDitheredTextureSet(cmd, sssrtParams.ditheredTextureSet); // For every sample that we need to process for (int sampleIndex = 0; sampleIndex < sssrtParams.sampleCount; ++sampleIndex) { // Inject the ray generation data sssrtParams.shaderVariablesRayTracingCB._RaytracingNumSamples = sssrtParams.sampleCount; sssrtParams.shaderVariablesRayTracingCB._RaytracingSampleIndex = sampleIndex; ConstantBuffer.PushGlobal(cmd, sssrtParams.shaderVariablesRayTracingCB, HDShaderIDs._ShaderVariablesRaytracing); // Bind the input textures for ray generation cmd.SetRayTracingTextureParam(sssrtParams.rayTracingSubSurfaceRT, HDShaderIDs._DepthTexture, sssrtResources.depthStencilBuffer); cmd.SetRayTracingTextureParam(sssrtParams.rayTracingSubSurfaceRT, HDShaderIDs._NormalBufferTexture, sssrtResources.normalBuffer); cmd.SetRayTracingTextureParam(sssrtParams.rayTracingSubSurfaceRT, HDShaderIDs._SSSBufferTexture, sssrtResources.sssColor); cmd.SetGlobalTexture(HDShaderIDs._StencilTexture, sssrtResources.depthStencilBuffer, RenderTextureSubElement.Stencil); // Set the output textures cmd.SetRayTracingTextureParam(sssrtParams.rayTracingSubSurfaceRT, HDShaderIDs._ThroughputTextureRW, sssrtResources.intermediateBuffer0); cmd.SetRayTracingTextureParam(sssrtParams.rayTracingSubSurfaceRT, HDShaderIDs._NormalTextureRW, sssrtResources.intermediateBuffer1); cmd.SetRayTracingTextureParam(sssrtParams.rayTracingSubSurfaceRT, HDShaderIDs._PositionTextureRW, sssrtResources.intermediateBuffer2); cmd.SetRayTracingTextureParam(sssrtParams.rayTracingSubSurfaceRT, HDShaderIDs._DiffuseLightingTextureRW, sssrtResources.intermediateBuffer3); cmd.SetRayTracingTextureParam(sssrtParams.rayTracingSubSurfaceRT, HDShaderIDs._DirectionTextureRW, sssrtResources.directionBuffer); // Run the computation cmd.DispatchRays(sssrtParams.rayTracingSubSurfaceRT, m_RayGenSubSurfaceShaderName, (uint)sssrtParams.texWidth, (uint)sssrtParams.texHeight, (uint)sssrtParams.viewCount); // Now let's do the deferred shading pass on the samples // Bind the lightLoop data sssrtParams.lightCluster.BindLightClusterData(cmd); // Bind the input textures cmd.SetComputeTextureParam(sssrtParams.deferredRayTracingCS, sssrtParams.rtDeferredLightingKernel, HDShaderIDs._DepthTexture, sssrtResources.depthStencilBuffer); cmd.SetComputeTextureParam(sssrtParams.deferredRayTracingCS, sssrtParams.rtDeferredLightingKernel, HDShaderIDs._ThroughputTextureRW, sssrtResources.intermediateBuffer0); cmd.SetComputeTextureParam(sssrtParams.deferredRayTracingCS, sssrtParams.rtDeferredLightingKernel, HDShaderIDs._NormalTextureRW, sssrtResources.intermediateBuffer1); cmd.SetComputeTextureParam(sssrtParams.deferredRayTracingCS, sssrtParams.rtDeferredLightingKernel, HDShaderIDs._PositionTextureRW, sssrtResources.intermediateBuffer2); cmd.SetComputeTextureParam(sssrtParams.deferredRayTracingCS, sssrtParams.rtDeferredLightingKernel, HDShaderIDs._DirectionTextureRW, sssrtResources.directionBuffer); cmd.SetComputeTextureParam(sssrtParams.deferredRayTracingCS, sssrtParams.rtDeferredLightingKernel, HDShaderIDs._DiffuseLightingTextureRW, sssrtResources.intermediateBuffer3); // Bind the output texture (it is used for accumulation read and write) cmd.SetComputeTextureParam(sssrtParams.deferredRayTracingCS, sssrtParams.rtDeferredLightingKernel, HDShaderIDs._RaytracingLitBufferRW, sssrtResources.outputBuffer); // Compute the Lighting cmd.DispatchCompute(sssrtParams.deferredRayTracingCS, sssrtParams.rtDeferredLightingKernel, numTilesXHR, numTilesYHR, sssrtParams.viewCount); } }