304 lines
17 KiB
C#
304 lines
17 KiB
C#
using UnityEngine.Experimental.Rendering;
|
|
using UnityEngine.Experimental.Rendering.RenderGraphModule;
|
|
|
|
namespace UnityEngine.Rendering.HighDefinition
|
|
{
|
|
public partial class HDRenderPipeline
|
|
{
|
|
class DirGenRTGIPassData
|
|
{
|
|
public RTIndirectDiffuseDirGenParameters parameters;
|
|
public TextureHandle depthStencilBuffer;
|
|
public TextureHandle normalBuffer;
|
|
public TextureHandle outputBuffer;
|
|
}
|
|
|
|
TextureHandle DirGenRTGI(RenderGraph renderGraph, in RTIndirectDiffuseDirGenParameters parameters, TextureHandle depthPyramid, TextureHandle normalBuffer)
|
|
{
|
|
using (var builder = renderGraph.AddRenderPass<DirGenRTGIPassData>("Generating the rays for RTGI", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingIndirectDiffuseDirectionGeneration)))
|
|
{
|
|
builder.EnableAsyncCompute(false);
|
|
|
|
passData.parameters = parameters;
|
|
passData.depthStencilBuffer = builder.ReadTexture(depthPyramid);
|
|
passData.normalBuffer = builder.ReadTexture(normalBuffer);
|
|
passData.outputBuffer = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
|
|
{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "GI Ray Directions" }));
|
|
|
|
builder.SetRenderFunc(
|
|
(DirGenRTGIPassData data, RenderGraphContext ctx) =>
|
|
{
|
|
// We need to fill the structure that holds the various resources
|
|
RTIndirectDiffuseDirGenResources rtgiDirGenResources = new RTIndirectDiffuseDirGenResources();
|
|
rtgiDirGenResources.depthStencilBuffer = data.depthStencilBuffer;
|
|
rtgiDirGenResources.normalBuffer = data.normalBuffer;
|
|
rtgiDirGenResources.outputBuffer = data.outputBuffer;
|
|
RTIndirectDiffuseDirGen(ctx.cmd, data.parameters, rtgiDirGenResources);
|
|
});
|
|
|
|
return passData.outputBuffer;
|
|
}
|
|
}
|
|
|
|
class UpscaleRTGIPassData
|
|
{
|
|
public RTIndirectDiffuseUpscaleParameters parameters;
|
|
public TextureHandle depthBuffer;
|
|
public TextureHandle normalBuffer;
|
|
public TextureHandle indirectDiffuseBuffer;
|
|
public TextureHandle directionBuffer;
|
|
public TextureHandle outputBuffer;
|
|
}
|
|
|
|
TextureHandle UpscaleRTGI(RenderGraph renderGraph, in RTIndirectDiffuseUpscaleParameters parameters,
|
|
TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle indirectDiffuseBuffer, TextureHandle directionBuffer)
|
|
{
|
|
using (var builder = renderGraph.AddRenderPass<UpscaleRTGIPassData>("Upscale the RTGI result", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingIndirectDiffuseUpscale)))
|
|
{
|
|
builder.EnableAsyncCompute(false);
|
|
|
|
passData.parameters = parameters;
|
|
passData.depthBuffer = builder.ReadTexture(depthPyramid);
|
|
passData.normalBuffer = builder.ReadTexture(normalBuffer);
|
|
passData.indirectDiffuseBuffer = builder.ReadTexture(indirectDiffuseBuffer);
|
|
passData.directionBuffer = builder.ReadTexture(directionBuffer);
|
|
passData.outputBuffer = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
|
|
{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Reflection Ray Indirect Diffuse" }));
|
|
|
|
builder.SetRenderFunc(
|
|
(UpscaleRTGIPassData data, RenderGraphContext ctx) =>
|
|
{
|
|
// We need to fill the structure that holds the various resources
|
|
RTIndirectDiffuseUpscaleResources rtgiUpscaleResources = new RTIndirectDiffuseUpscaleResources();
|
|
rtgiUpscaleResources.depthStencilBuffer = data.depthBuffer;
|
|
rtgiUpscaleResources.normalBuffer = data.normalBuffer;
|
|
rtgiUpscaleResources.indirectDiffuseBuffer = data.indirectDiffuseBuffer;
|
|
rtgiUpscaleResources.directionBuffer = data.directionBuffer;
|
|
rtgiUpscaleResources.outputBuffer = data.outputBuffer;
|
|
RTIndirectDiffuseUpscale(ctx.cmd, data.parameters, rtgiUpscaleResources);
|
|
});
|
|
|
|
return passData.outputBuffer;
|
|
}
|
|
}
|
|
|
|
class AdjustRTGIWeightPassData
|
|
{
|
|
public AdjustRTIDWeightParameters parameters;
|
|
public TextureHandle depthPyramid;
|
|
public TextureHandle stencilBuffer;
|
|
public TextureHandle indirectDiffuseBuffer;
|
|
}
|
|
|
|
TextureHandle AdjustRTGIWeight(RenderGraph renderGraph, in AdjustRTIDWeightParameters parameters, TextureHandle indirectDiffuseBuffer, TextureHandle depthPyramid, TextureHandle stencilBuffer)
|
|
{
|
|
using (var builder = renderGraph.AddRenderPass<AdjustRTGIWeightPassData>("Adjust the RTGI weight", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingIndirectDiffuseAdjustWeight)))
|
|
{
|
|
builder.EnableAsyncCompute(false);
|
|
|
|
passData.parameters = parameters;
|
|
passData.depthPyramid = builder.ReadTexture(depthPyramid);
|
|
passData.stencilBuffer = builder.ReadTexture(stencilBuffer);
|
|
passData.indirectDiffuseBuffer = builder.ReadWriteTexture(indirectDiffuseBuffer);
|
|
|
|
builder.SetRenderFunc(
|
|
(AdjustRTGIWeightPassData data, RenderGraphContext ctx) =>
|
|
{
|
|
// We need to fill the structure that holds the various resources
|
|
AdjustRTIDWeight(ctx.cmd, data.parameters, data.indirectDiffuseBuffer, data.depthPyramid, data.stencilBuffer);
|
|
});
|
|
|
|
return passData.indirectDiffuseBuffer;
|
|
}
|
|
}
|
|
|
|
static RTHandle RequestRayTracedIndirectDiffuseHistoryTexture(HDCamera hdCamera)
|
|
{
|
|
return hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedIndirectDiffuseHF)
|
|
?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedIndirectDiffuseHF,
|
|
ReflectionHistoryBufferAllocatorFunction, 1);
|
|
}
|
|
|
|
TextureHandle RenderIndirectDiffusePerformance(RenderGraph renderGraph, HDCamera hdCamera,
|
|
TextureHandle depthPyramid, TextureHandle stencilBuffer, TextureHandle normalBuffer, TextureHandle motionVectors, TextureHandle historyValidationTexture,
|
|
TextureHandle rayCountTexture, Texture skyTexture,
|
|
ShaderVariablesRaytracing shaderVariablesRaytracing)
|
|
{
|
|
// Pointer to the final result
|
|
TextureHandle rtgiResult;
|
|
|
|
// Fetch all the settings
|
|
GlobalIllumination settings = hdCamera.volumeStack.GetComponent<GlobalIllumination>();
|
|
|
|
RTIndirectDiffuseDirGenParameters rtgiDirGenParameters = PrepareRTIndirectDiffuseDirGenParameters(hdCamera, settings);
|
|
TextureHandle directionBuffer = DirGenRTGI(renderGraph, in rtgiDirGenParameters, depthPyramid, normalBuffer);
|
|
|
|
DeferredLightingRTParameters deferredParamters = PrepareIndirectDiffuseDeferredLightingRTParameters(hdCamera);
|
|
TextureHandle lightingBuffer = DeferredLightingRT(renderGraph, in deferredParamters, directionBuffer, depthPyramid, normalBuffer, skyTexture, rayCountTexture);
|
|
|
|
RTIndirectDiffuseUpscaleParameters rtgiUpscaleParameters = PrepareRTIndirectDiffuseUpscaleParameters(hdCamera, settings);
|
|
rtgiResult = UpscaleRTGI(renderGraph, in rtgiUpscaleParameters,
|
|
depthPyramid, normalBuffer, lightingBuffer, directionBuffer);
|
|
// Denoise if required
|
|
rtgiResult = DenoiseRTGI(renderGraph, hdCamera, rtgiResult, depthPyramid, normalBuffer, motionVectors, historyValidationTexture);
|
|
|
|
// Adjust the weight
|
|
AdjustRTIDWeightParameters artidParamters = PrepareAdjustRTIDWeightParametersParameters(hdCamera);
|
|
rtgiResult = AdjustRTGIWeight(renderGraph, in artidParamters, rtgiResult, depthPyramid, stencilBuffer);
|
|
|
|
return rtgiResult;
|
|
}
|
|
|
|
class TraceQualityRTGIPassData
|
|
{
|
|
public QualityRTIndirectDiffuseParameters parameters;
|
|
public TextureHandle depthBuffer;
|
|
public TextureHandle normalBuffer;
|
|
public TextureHandle rayCountTexture;
|
|
public TextureHandle outputBuffer;
|
|
}
|
|
|
|
TextureHandle QualityRTGI(RenderGraph renderGraph, in QualityRTIndirectDiffuseParameters parameters, TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle rayCountTexture)
|
|
{
|
|
using (var builder = renderGraph.AddRenderPass<TraceQualityRTGIPassData>("Quality RT Indirect Diffuse", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingIndirectDiffuseEvaluation)))
|
|
{
|
|
builder.EnableAsyncCompute(false);
|
|
|
|
passData.parameters = parameters;
|
|
passData.depthBuffer = builder.ReadTexture(depthPyramid);
|
|
passData.normalBuffer = builder.ReadTexture(normalBuffer);
|
|
passData.rayCountTexture = builder.ReadWriteTexture(rayCountTexture);
|
|
passData.outputBuffer = builder.WriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
|
|
{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Ray Traced Indirect Diffuse" }));
|
|
|
|
builder.SetRenderFunc(
|
|
(TraceQualityRTGIPassData data, RenderGraphContext ctx) =>
|
|
{
|
|
// We need to fill the structure that holds the various resources
|
|
QualityRTIndirectDiffuseResources rtgiQRenderingResources = new QualityRTIndirectDiffuseResources();
|
|
rtgiQRenderingResources.depthBuffer = data.depthBuffer;
|
|
rtgiQRenderingResources.normalBuffer = data.normalBuffer;
|
|
rtgiQRenderingResources.rayCountTexture = data.rayCountTexture;
|
|
rtgiQRenderingResources.outputBuffer = data.outputBuffer;
|
|
RenderQualityRayTracedIndirectDiffuse(ctx.cmd, data.parameters, rtgiQRenderingResources);
|
|
});
|
|
|
|
return passData.outputBuffer;
|
|
}
|
|
}
|
|
|
|
TextureHandle RenderIndirectDiffuseQuality(RenderGraph renderGraph, HDCamera hdCamera,
|
|
TextureHandle depthPyramid, TextureHandle stencilBuffer, TextureHandle normalBuffer, TextureHandle motionVectors, TextureHandle historyValidationTexture,
|
|
TextureHandle rayCountTexture, Texture skyTexture,
|
|
ShaderVariablesRaytracing shaderVariablesRaytracing)
|
|
{
|
|
var settings = hdCamera.volumeStack.GetComponent<GlobalIllumination>();
|
|
|
|
// Evaluate the signal
|
|
QualityRTIndirectDiffuseParameters rtgiQRenderingParameters = PrepareQualityRTIndirectDiffuseParameters(hdCamera, settings);
|
|
TextureHandle rtgiResult = QualityRTGI(renderGraph, in rtgiQRenderingParameters, depthPyramid, normalBuffer, rayCountTexture);
|
|
|
|
// Denoise if required
|
|
rtgiResult = DenoiseRTGI(renderGraph, hdCamera, rtgiResult, depthPyramid, normalBuffer, motionVectors, historyValidationTexture);
|
|
|
|
// Adjust the weight
|
|
AdjustRTIDWeightParameters artidParamters = PrepareAdjustRTIDWeightParametersParameters(hdCamera);
|
|
rtgiResult = AdjustRTGIWeight(renderGraph, in artidParamters, rtgiResult, depthPyramid, stencilBuffer);
|
|
|
|
return rtgiResult;
|
|
}
|
|
|
|
static RTHandle RequestIndirectDiffuseHistoryTextureHF(HDCamera hdCamera)
|
|
{
|
|
return hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedIndirectDiffuseHF)
|
|
?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedIndirectDiffuseHF,
|
|
IndirectDiffuseHistoryBufferAllocatorFunction, 1);
|
|
}
|
|
|
|
static RTHandle RequestIndirectDiffuseHistoryTextureLF(HDCamera hdCamera)
|
|
{
|
|
return hdCamera.GetCurrentFrameRT((int)HDCameraFrameHistoryType.RaytracedIndirectDiffuseLF)
|
|
?? hdCamera.AllocHistoryFrameRT((int)HDCameraFrameHistoryType.RaytracedIndirectDiffuseLF,
|
|
IndirectDiffuseHistoryBufferAllocatorFunction, 1);
|
|
}
|
|
|
|
TextureHandle DenoiseRTGI(RenderGraph renderGraph, HDCamera hdCamera, TextureHandle rtGIBuffer, TextureHandle depthPyramid, TextureHandle normalBuffer, TextureHandle motionVectorBuffer, TextureHandle historyValidationTexture)
|
|
{
|
|
var giSettings = hdCamera.volumeStack.GetComponent<GlobalIllumination>();
|
|
if (giSettings.denoise)
|
|
{
|
|
// Evaluate the history's validity
|
|
float historyValidity0 = EvaluateIndirectDiffuseHistoryValidity0(hdCamera, giSettings.fullResolution, true);
|
|
|
|
HDTemporalFilter temporalFilter = GetTemporalFilter();
|
|
HDDiffuseDenoiser diffuseDenoiser = GetDiffuseDenoiser();
|
|
|
|
// Run the temporal denoiser
|
|
TemporalFilterParameters tfParameters = temporalFilter.PrepareTemporalFilterParameters(hdCamera, false, historyValidity0);
|
|
TextureHandle historyBufferHF = renderGraph.ImportTexture(RequestIndirectDiffuseHistoryTextureHF(hdCamera));
|
|
TextureHandle denoisedRTGI = temporalFilter.Denoise(renderGraph, hdCamera, tfParameters, rtGIBuffer, renderGraph.defaultResources.blackTextureXR, historyBufferHF, depthPyramid, normalBuffer, motionVectorBuffer, historyValidationTexture);
|
|
|
|
// Apply the diffuse denoiser
|
|
DiffuseDenoiserParameters ddParams = diffuseDenoiser.PrepareDiffuseDenoiserParameters(hdCamera, false, giSettings.denoiserRadius, giSettings.halfResolutionDenoiser, giSettings.secondDenoiserPass);
|
|
rtGIBuffer = diffuseDenoiser.Denoise(renderGraph, hdCamera, ddParams, denoisedRTGI, depthPyramid, normalBuffer, rtGIBuffer);
|
|
|
|
// If the second pass is requested, do it otherwise blit
|
|
if (giSettings.secondDenoiserPass)
|
|
{
|
|
float historyValidity1 = EvaluateIndirectDiffuseHistoryValidity1(hdCamera, giSettings.fullResolution, true);
|
|
|
|
// Run the temporal denoiser
|
|
tfParameters = temporalFilter.PrepareTemporalFilterParameters(hdCamera, false, historyValidity1);
|
|
TextureHandle historyBufferLF = renderGraph.ImportTexture(RequestIndirectDiffuseHistoryTextureLF(hdCamera));
|
|
denoisedRTGI = temporalFilter.Denoise(renderGraph, hdCamera, tfParameters, rtGIBuffer, renderGraph.defaultResources.blackTextureXR, historyBufferLF, depthPyramid, normalBuffer, motionVectorBuffer, historyValidationTexture);
|
|
|
|
// Apply the diffuse denoiser
|
|
ddParams = diffuseDenoiser.PrepareDiffuseDenoiserParameters(hdCamera, false, giSettings.denoiserRadius * 0.5f, giSettings.halfResolutionDenoiser, false);
|
|
rtGIBuffer = diffuseDenoiser.Denoise(renderGraph, hdCamera, ddParams, denoisedRTGI, depthPyramid, normalBuffer, rtGIBuffer);
|
|
|
|
// Propagate the history validity for the second buffer
|
|
PropagateIndirectDiffuseHistoryValidity1(hdCamera, giSettings.fullResolution, true);
|
|
}
|
|
|
|
// Propagate the history validity for the first buffer
|
|
PropagateIndirectDiffuseHistoryValidity0(hdCamera, giSettings.fullResolution, true);
|
|
|
|
return rtGIBuffer;
|
|
}
|
|
else
|
|
return rtGIBuffer;
|
|
}
|
|
|
|
TextureHandle RenderRayTracedIndirectDiffuse(RenderGraph renderGraph, HDCamera hdCamera,
|
|
TextureHandle depthPyramid, TextureHandle stencilBuffer, TextureHandle normalBuffer, TextureHandle motionVectors, TextureHandle historyValidationTexture,
|
|
Texture skyTexture, TextureHandle rayCountTexture,
|
|
ShaderVariablesRaytracing shaderVariablesRaytracing)
|
|
{
|
|
GlobalIllumination giSettings = hdCamera.volumeStack.GetComponent<GlobalIllumination>();
|
|
|
|
TextureHandle rtreflResult;
|
|
bool qualityMode = false;
|
|
|
|
// Based on what the asset supports, follow the volume or force the right mode.
|
|
if (m_Asset.currentPlatformRenderPipelineSettings.supportedRayTracingMode == RenderPipelineSettings.SupportedRayTracingMode.Both)
|
|
qualityMode = giSettings.mode.value == RayTracingMode.Quality;
|
|
else
|
|
qualityMode = m_Asset.currentPlatformRenderPipelineSettings.supportedRayTracingMode == RenderPipelineSettings.SupportedRayTracingMode.Quality;
|
|
|
|
|
|
if (qualityMode)
|
|
rtreflResult = RenderIndirectDiffuseQuality(renderGraph, hdCamera,
|
|
depthPyramid, stencilBuffer, normalBuffer, motionVectors, historyValidationTexture,
|
|
rayCountTexture, skyTexture,
|
|
shaderVariablesRaytracing);
|
|
else
|
|
rtreflResult = RenderIndirectDiffusePerformance(renderGraph, hdCamera,
|
|
depthPyramid, stencilBuffer, normalBuffer, motionVectors, historyValidationTexture,
|
|
rayCountTexture, skyTexture,
|
|
shaderVariablesRaytracing);
|
|
|
|
return rtreflResult;
|
|
}
|
|
}
|
|
}
|