Rasagar/Library/PackageCache/com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/Raytracing/HDDiffuseDenoiser.cs
2024-08-26 23:07:20 +03:00

174 lines
9.7 KiB
C#

using UnityEngine.Experimental.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering;
namespace UnityEngine.Rendering.HighDefinition
{
class HDDiffuseDenoiser
{
// Resources used for the de-noiser
ComputeShader m_DiffuseDenoiser;
// Runtime Initialization data
bool m_DenoiserInitialized;
Texture2D m_OwnenScrambledTexture;
GraphicsBuffer m_PointDistribution;
// Kernels that may be required
int m_BilateralFilterSingleKernel;
int m_BilateralFilterColorKernel;
int m_GatherSingleKernel;
int m_GatherColorKernel;
public void Init(HDRenderPipeline renderPipeline)
{
// Keep track of the resources
m_DiffuseDenoiser = renderPipeline.runtimeShaders.diffuseDenoiserCS;
// Grab all the kernels we'll eventually need
m_BilateralFilterSingleKernel = m_DiffuseDenoiser.FindKernel("BilateralFilterSingle");
m_BilateralFilterColorKernel = m_DiffuseDenoiser.FindKernel("BilateralFilterColor");
m_GatherSingleKernel = m_DiffuseDenoiser.FindKernel("GatherSingle");
m_GatherColorKernel = m_DiffuseDenoiser.FindKernel("GatherColor");
// Data required for the online initialization
m_DenoiserInitialized = false;
m_OwnenScrambledTexture = renderPipeline.runtimeTextures.owenScrambledRGBATex;
m_PointDistribution = new GraphicsBuffer(GraphicsBuffer.Target.Structured, 16 * 4, 2 * sizeof(float));
}
public void Release()
{
CoreUtils.SafeRelease(m_PointDistribution);
}
class DiffuseDenoiserPassData
{
// Camera parameters
public int texWidth;
public int texHeight;
public int viewCount;
// Denoising parameters
public bool needInit;
public float pixelSpreadTangent;
public float kernelSize;
public bool halfResolutionFilter;
public bool jitterFilter;
public int frameIndex;
public float resolutionMultiplier;
// Kernels
public int bilateralFilterKernel;
public int gatherKernel;
// Other parameters
public BufferHandle pointDistribution;
public ComputeShader diffuseDenoiserCS;
public Texture2D owenScrambledTexture;
public TextureHandle depthStencilBuffer;
public TextureHandle normalBuffer;
public TextureHandle noisyBuffer;
public TextureHandle intermediateBuffer;
public TextureHandle outputBuffer;
}
internal struct DiffuseDenoiserParameters
{
public bool singleChannel;
public float kernelSize;
public bool halfResolutionFilter;
public bool jitterFilter;
public float resolutionMultiplier;
}
public TextureHandle Denoise(RenderGraph renderGraph, HDCamera hdCamera, DiffuseDenoiserParameters denoiserParams,
TextureHandle noisyBuffer, TextureHandle depthBuffer, TextureHandle normalBuffer, TextureHandle outputBuffer)
{
using (var builder = renderGraph.AddRenderPass<DiffuseDenoiserPassData>("DiffuseDenoiser", out var passData, ProfilingSampler.Get(HDProfileId.DiffuseFilter)))
{
// Cannot run in async
builder.EnableAsyncCompute(false);
// Initialization data
passData.needInit = !m_DenoiserInitialized;
m_DenoiserInitialized = true;
passData.owenScrambledTexture = m_OwnenScrambledTexture;
// Camera parameters
passData.texWidth = (int)Mathf.Floor(hdCamera.actualWidth / denoiserParams.resolutionMultiplier);
passData.texHeight = (int)Mathf.Floor(hdCamera.actualHeight / denoiserParams.resolutionMultiplier);
passData.viewCount = hdCamera.viewCount;
// Parameters
passData.pixelSpreadTangent = HDRenderPipeline.GetPixelSpreadTangent(hdCamera.camera.fieldOfView, passData.texWidth, passData.texHeight);
passData.kernelSize = denoiserParams.kernelSize;
passData.halfResolutionFilter = denoiserParams.halfResolutionFilter;
passData.jitterFilter = denoiserParams.jitterFilter;
passData.frameIndex = HDRenderPipeline.RayTracingFrameIndex(hdCamera);
passData.resolutionMultiplier = denoiserParams.resolutionMultiplier;
// Kernels
passData.bilateralFilterKernel = denoiserParams.singleChannel ? m_BilateralFilterSingleKernel : m_BilateralFilterColorKernel;
passData.gatherKernel = denoiserParams.singleChannel ? m_GatherSingleKernel : m_GatherColorKernel;
// Other parameters
passData.diffuseDenoiserCS = m_DiffuseDenoiser;
passData.pointDistribution = builder.ReadBuffer(renderGraph.ImportBuffer(m_PointDistribution));
passData.depthStencilBuffer = builder.ReadTexture(depthBuffer);
passData.normalBuffer = builder.ReadTexture(normalBuffer);
passData.noisyBuffer = builder.ReadTexture(noisyBuffer);
passData.intermediateBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true) { colorFormat = GraphicsFormat.B10G11R11_UFloatPack32, enableRandomWrite = true, name = "DiffuseDenoiserIntermediate" });
passData.outputBuffer = builder.WriteTexture(outputBuffer);
builder.SetRenderFunc(
(DiffuseDenoiserPassData data, RenderGraphContext ctx) =>
{
// Generate the point distribution if needed (this is only ran once)
if (data.needInit)
{
int m_GeneratePointDistributionKernel = data.diffuseDenoiserCS.FindKernel("GeneratePointDistribution");
ctx.cmd.SetComputeTextureParam(data.diffuseDenoiserCS, m_GeneratePointDistributionKernel, HDShaderIDs._OwenScrambledRGTexture, data.owenScrambledTexture);
ctx.cmd.SetComputeBufferParam(data.diffuseDenoiserCS, m_GeneratePointDistributionKernel, "_PointDistributionRW", data.pointDistribution);
ctx.cmd.DispatchCompute(data.diffuseDenoiserCS, m_GeneratePointDistributionKernel, 1, 1, 1);
}
// Evaluate the dispatch parameters
int areaTileSize = 8;
int numTilesX = (data.texWidth + (areaTileSize - 1)) / areaTileSize;
int numTilesY = (data.texHeight + (areaTileSize - 1)) / areaTileSize;
// Request the intermediate buffers that we need
ctx.cmd.SetComputeFloatParam(data.diffuseDenoiserCS, HDShaderIDs._DenoiserFilterRadius, data.kernelSize);
ctx.cmd.SetComputeBufferParam(data.diffuseDenoiserCS, data.bilateralFilterKernel, HDShaderIDs._PointDistribution, data.pointDistribution);
ctx.cmd.SetComputeTextureParam(data.diffuseDenoiserCS, data.bilateralFilterKernel, HDShaderIDs._DenoiseInputTexture, data.noisyBuffer);
ctx.cmd.SetComputeTextureParam(data.diffuseDenoiserCS, data.bilateralFilterKernel, HDShaderIDs._DepthTexture, data.depthStencilBuffer);
ctx.cmd.SetComputeTextureParam(data.diffuseDenoiserCS, data.bilateralFilterKernel, HDShaderIDs._StencilTexture, data.depthStencilBuffer, 0, RenderTextureSubElement.Stencil);
ctx.cmd.SetComputeTextureParam(data.diffuseDenoiserCS, data.bilateralFilterKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer);
ctx.cmd.SetComputeTextureParam(data.diffuseDenoiserCS, data.bilateralFilterKernel, HDShaderIDs._DenoiseOutputTextureRW, data.halfResolutionFilter ? data.intermediateBuffer : data.outputBuffer);
ctx.cmd.SetComputeIntParam(data.diffuseDenoiserCS, HDShaderIDs._HalfResolutionFilter, data.halfResolutionFilter ? 1 : 0);
ctx.cmd.SetComputeFloatParam(data.diffuseDenoiserCS, HDShaderIDs._PixelSpreadAngleTangent, data.pixelSpreadTangent);
ctx.cmd.SetComputeVectorParam(data.diffuseDenoiserCS, HDShaderIDs._DenoiserResolutionMultiplierVals, new Vector4(data.resolutionMultiplier, 1.0f / data.resolutionMultiplier, 0.0f, 0.0f));
if (data.jitterFilter)
ctx.cmd.SetComputeIntParam(data.diffuseDenoiserCS, HDShaderIDs._JitterFramePeriod, (data.frameIndex % 4));
else
ctx.cmd.SetComputeIntParam(data.diffuseDenoiserCS, HDShaderIDs._JitterFramePeriod, -1);
ctx.cmd.DispatchCompute(data.diffuseDenoiserCS, data.bilateralFilterKernel, numTilesX, numTilesY, data.viewCount);
if (data.halfResolutionFilter)
{
ctx.cmd.SetComputeTextureParam(data.diffuseDenoiserCS, data.gatherKernel, HDShaderIDs._DenoiseInputTexture, data.intermediateBuffer);
ctx.cmd.SetComputeTextureParam(data.diffuseDenoiserCS, data.gatherKernel, HDShaderIDs._DepthTexture, data.depthStencilBuffer);
ctx.cmd.SetComputeTextureParam(data.diffuseDenoiserCS, data.gatherKernel, HDShaderIDs._DenoiseOutputTextureRW, data.outputBuffer);
ctx.cmd.DispatchCompute(data.diffuseDenoiserCS, data.gatherKernel, numTilesX, numTilesY, data.viewCount);
}
});
return passData.outputBuffer;
}
}
}
}