You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
345 lines
19 KiB
345 lines
19 KiB
using UnityEngine.Experimental.Rendering;
|
|
using UnityEngine.Rendering.RenderGraphModule;
|
|
|
|
namespace UnityEngine.Rendering.HighDefinition
|
|
{
|
|
class HDDiffuseShadowDenoiser
|
|
{
|
|
// The resources quired by this component
|
|
ComputeShader m_ShadowDenoiser;
|
|
|
|
// Kernels that we are using
|
|
int m_BilateralFilterHSingleDirectionalKernel;
|
|
int m_BilateralFilterVSingleDirectionalKernel;
|
|
|
|
int m_BilateralFilterHColorDirectionalKernel;
|
|
int m_BilateralFilterVColorDirectionalKernel;
|
|
|
|
int m_BilateralFilterHSinglePointKernel;
|
|
int m_BilateralFilterVSinglePointKernel;
|
|
|
|
int m_BilateralFilterHSingleSpotKernel;
|
|
int m_BilateralFilterVSingleSpotKernel;
|
|
|
|
int m_BilateralFilterHSinglePyramidKernel;
|
|
int m_BilateralFilterVSinglePyramidKernel;
|
|
|
|
int m_BilateralFilterHSingleBoxKernel;
|
|
int m_BilateralFilterVSingleBoxKernel;
|
|
|
|
public HDDiffuseShadowDenoiser()
|
|
{
|
|
}
|
|
|
|
public void Init(HDRPRayTracingResources rpRTResources)
|
|
{
|
|
m_ShadowDenoiser = rpRTResources.diffuseShadowDenoiserCS;
|
|
|
|
m_BilateralFilterHSingleDirectionalKernel = m_ShadowDenoiser.FindKernel("BilateralFilterHSingleDirectional");
|
|
m_BilateralFilterVSingleDirectionalKernel = m_ShadowDenoiser.FindKernel("BilateralFilterVSingleDirectional");
|
|
|
|
m_BilateralFilterHColorDirectionalKernel = m_ShadowDenoiser.FindKernel("BilateralFilterHColorDirectional");
|
|
m_BilateralFilterVColorDirectionalKernel = m_ShadowDenoiser.FindKernel("BilateralFilterVColorDirectional");
|
|
|
|
m_BilateralFilterHSinglePointKernel = m_ShadowDenoiser.FindKernel("BilateralFilterHSinglePoint");
|
|
m_BilateralFilterVSinglePointKernel = m_ShadowDenoiser.FindKernel("BilateralFilterVSinglePoint");
|
|
|
|
m_BilateralFilterHSingleSpotKernel = m_ShadowDenoiser.FindKernel("BilateralFilterHSingleSpot");
|
|
m_BilateralFilterVSingleSpotKernel = m_ShadowDenoiser.FindKernel("BilateralFilterVSingleSpot");
|
|
|
|
m_BilateralFilterHSinglePyramidKernel = m_ShadowDenoiser.FindKernel("BilateralFilterHSinglePyramid");
|
|
m_BilateralFilterVSinglePyramidKernel = m_ShadowDenoiser.FindKernel("BilateralFilterVSinglePyramid");
|
|
|
|
m_BilateralFilterHSingleBoxKernel = m_ShadowDenoiser.FindKernel("BilateralFilterHSingleBox");
|
|
m_BilateralFilterVSingleBoxKernel = m_ShadowDenoiser.FindKernel("BilateralFilterVSingleBox");
|
|
}
|
|
|
|
public void Release()
|
|
{
|
|
}
|
|
|
|
class DiffuseShadowDenoiserDirectionalPassData
|
|
{
|
|
// Camera parameters
|
|
public int texWidth;
|
|
public int texHeight;
|
|
public int viewCount;
|
|
|
|
// Evaluation parameters
|
|
public float lightAngle;
|
|
public float cameraFov;
|
|
public int kernelSize;
|
|
|
|
// Kernels
|
|
public int bilateralHKernel;
|
|
public int bilateralVKernel;
|
|
|
|
// Other parameters
|
|
public ComputeShader diffuseShadowDenoiserCS;
|
|
|
|
public TextureHandle depthStencilBuffer;
|
|
public TextureHandle normalBuffer;
|
|
public TextureHandle distanceBuffer;
|
|
public TextureHandle noisyBuffer;
|
|
public TextureHandle intermediateBuffer;
|
|
public TextureHandle outputBuffer;
|
|
}
|
|
|
|
public TextureHandle DenoiseBufferDirectional(RenderGraph renderGraph, HDCamera hdCamera,
|
|
TextureHandle depthBuffer, TextureHandle normalBuffer,
|
|
TextureHandle noisyBuffer, TextureHandle distanceBuffer,
|
|
int kernelSize, float angularDiameter, bool singleChannel = true)
|
|
{
|
|
using (var builder = renderGraph.AddRenderPass<DiffuseShadowDenoiserDirectionalPassData>("TemporalDenoiser", out var passData, ProfilingSampler.Get(HDProfileId.DiffuseFilter)))
|
|
{
|
|
// Cannot run in async
|
|
builder.EnableAsyncCompute(false);
|
|
|
|
// Fetch all the resources
|
|
// Set the camera parameters
|
|
passData.texWidth = hdCamera.actualWidth;
|
|
passData.texHeight = hdCamera.actualHeight;
|
|
passData.viewCount = hdCamera.viewCount;
|
|
|
|
// Evaluation parameters
|
|
passData.cameraFov = hdCamera.camera.fieldOfView * Mathf.PI / 180.0f;
|
|
// Convert the angular diameter of the directional light to radians (from degrees)
|
|
passData.lightAngle = angularDiameter * Mathf.PI / 180.0f;
|
|
passData.kernelSize = kernelSize;
|
|
|
|
// Kernels
|
|
passData.bilateralHKernel = singleChannel ? m_BilateralFilterHSingleDirectionalKernel : m_BilateralFilterHColorDirectionalKernel;
|
|
passData.bilateralVKernel = singleChannel ? m_BilateralFilterVSingleDirectionalKernel : m_BilateralFilterVColorDirectionalKernel;
|
|
|
|
// Other parameters
|
|
passData.diffuseShadowDenoiserCS = m_ShadowDenoiser;
|
|
|
|
// Input buffers
|
|
passData.depthStencilBuffer = builder.UseDepthBuffer(depthBuffer, DepthAccess.Read);
|
|
passData.normalBuffer = builder.ReadTexture(normalBuffer);
|
|
passData.distanceBuffer = builder.ReadTexture(distanceBuffer);
|
|
passData.noisyBuffer = builder.ReadTexture(noisyBuffer);
|
|
|
|
// Temporary buffers
|
|
passData.intermediateBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
|
|
{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Intermediate buffer" });
|
|
|
|
// Output buffer
|
|
passData.outputBuffer = builder.ReadWriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
|
|
{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Denoised Buffer" }));
|
|
|
|
|
|
builder.SetRenderFunc(
|
|
(DiffuseShadowDenoiserDirectionalPassData data, RenderGraphContext ctx) =>
|
|
{
|
|
// Raise the distance based denoiser keyword
|
|
CoreUtils.SetKeyword(ctx.cmd, "DISTANCE_BASED_DENOISER", true);
|
|
|
|
// Evaluate the dispatch parameters
|
|
int denoiserTileSize = 8;
|
|
int numTilesX = (data.texWidth + (denoiserTileSize - 1)) / denoiserTileSize;
|
|
int numTilesY = (data.texHeight + (denoiserTileSize - 1)) / denoiserTileSize;
|
|
|
|
// Bind input uniforms for both dispatches
|
|
ctx.cmd.SetComputeFloatParam(data.diffuseShadowDenoiserCS, HDShaderIDs._RaytracingLightAngle, data.lightAngle);
|
|
ctx.cmd.SetComputeIntParam(data.diffuseShadowDenoiserCS, HDShaderIDs._DenoiserFilterRadius, data.kernelSize);
|
|
ctx.cmd.SetComputeFloatParam(data.diffuseShadowDenoiserCS, HDShaderIDs._CameraFOV, data.cameraFov);
|
|
|
|
// Bind Input Textures
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralHKernel, HDShaderIDs._DepthTexture, data.depthStencilBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralHKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralHKernel, HDShaderIDs._DenoiseInputTexture, data.noisyBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralHKernel, HDShaderIDs._DistanceTexture, data.distanceBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralHKernel, HDShaderIDs._StencilTexture, data.depthStencilBuffer, 0, RenderTextureSubElement.Stencil);
|
|
|
|
// Bind output textures
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralHKernel, HDShaderIDs._DenoiseOutputTextureRW, data.intermediateBuffer);
|
|
|
|
// Do the Horizontal pass
|
|
ctx.cmd.DispatchCompute(data.diffuseShadowDenoiserCS, data.bilateralHKernel, numTilesX, numTilesY, data.viewCount);
|
|
|
|
// Bind Input Textures
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralVKernel, HDShaderIDs._DepthTexture, data.depthStencilBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralVKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralVKernel, HDShaderIDs._DenoiseInputTexture, data.intermediateBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralVKernel, HDShaderIDs._DistanceTexture, data.distanceBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralVKernel, HDShaderIDs._StencilTexture, data.depthStencilBuffer, 0, RenderTextureSubElement.Stencil);
|
|
|
|
// Bind output textures
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralVKernel, HDShaderIDs._DenoiseOutputTextureRW, data.outputBuffer);
|
|
|
|
// Do the Vertical pass
|
|
ctx.cmd.DispatchCompute(data.diffuseShadowDenoiserCS, data.bilateralVKernel, numTilesX, numTilesY, data.viewCount);
|
|
|
|
CoreUtils.SetKeyword(ctx.cmd, "DISTANCE_BASED_DENOISER", false);
|
|
});
|
|
return passData.outputBuffer;
|
|
}
|
|
}
|
|
|
|
class DiffuseShadowDenoiserSpherePassData
|
|
{
|
|
// Camera parameters
|
|
public int texWidth;
|
|
public int texHeight;
|
|
public int viewCount;
|
|
|
|
// Evaluation parameters
|
|
public float cameraFov;
|
|
public PunctualShadowProperties properties;
|
|
|
|
// Kernels
|
|
public int bilateralHKernel;
|
|
public int bilateralVKernel;
|
|
|
|
// Other parameters
|
|
public ComputeShader diffuseShadowDenoiserCS;
|
|
|
|
public TextureHandle depthStencilBuffer;
|
|
public TextureHandle normalBuffer;
|
|
public TextureHandle distanceBuffer;
|
|
public TextureHandle noisyBuffer;
|
|
public TextureHandle intermediateBuffer;
|
|
public TextureHandle outputBuffer;
|
|
}
|
|
|
|
public TextureHandle DenoiseBufferSphere(RenderGraph renderGraph, HDCamera hdCamera,
|
|
TextureHandle depthBuffer, TextureHandle normalBuffer,
|
|
TextureHandle noisyBuffer, TextureHandle distanceBuffer,
|
|
PunctualShadowProperties properties)
|
|
{
|
|
using (var builder = renderGraph.AddRenderPass<DiffuseShadowDenoiserSpherePassData>("DiffuseDenoiser", out var passData, ProfilingSampler.Get(HDProfileId.DiffuseFilter)))
|
|
{
|
|
// Cannot run in async
|
|
builder.EnableAsyncCompute(false);
|
|
|
|
// Set the camera parameters
|
|
passData.texWidth = hdCamera.actualWidth;
|
|
passData.texHeight = hdCamera.actualHeight;
|
|
passData.viewCount = hdCamera.viewCount;
|
|
|
|
// Evaluation parameters
|
|
passData.cameraFov = hdCamera.camera.fieldOfView * Mathf.PI / 180.0f;
|
|
passData.properties = properties;
|
|
|
|
// Make sure the position is in the right space before injecting it
|
|
if (ShaderConfig.s_CameraRelativeRendering != 0)
|
|
passData.properties.lightPosition -= hdCamera.camera.transform.position;
|
|
|
|
// Kernels
|
|
|
|
switch (properties.lightType)
|
|
{
|
|
case GPULightType.Spot:
|
|
{
|
|
passData.bilateralHKernel = m_BilateralFilterHSingleSpotKernel;
|
|
passData.bilateralVKernel = m_BilateralFilterVSingleSpotKernel;
|
|
}
|
|
break;
|
|
case GPULightType.ProjectorPyramid:
|
|
{
|
|
passData.bilateralHKernel = m_BilateralFilterHSinglePyramidKernel;
|
|
passData.bilateralVKernel = m_BilateralFilterVSinglePyramidKernel;
|
|
}
|
|
break;
|
|
case GPULightType.ProjectorBox:
|
|
{
|
|
passData.bilateralHKernel = m_BilateralFilterHSingleBoxKernel;
|
|
passData.bilateralVKernel = m_BilateralFilterVSingleBoxKernel;
|
|
}
|
|
break;
|
|
case GPULightType.Point:
|
|
default:
|
|
{
|
|
passData.bilateralHKernel = m_BilateralFilterHSinglePointKernel;
|
|
passData.bilateralVKernel = m_BilateralFilterVSinglePointKernel;
|
|
}
|
|
break;
|
|
}
|
|
|
|
// Other parameters
|
|
passData.diffuseShadowDenoiserCS = m_ShadowDenoiser;
|
|
|
|
// Input buffers
|
|
passData.depthStencilBuffer = builder.UseDepthBuffer(depthBuffer, DepthAccess.Read);
|
|
passData.normalBuffer = builder.ReadTexture(normalBuffer);
|
|
if (properties.distanceBasedDenoiser)
|
|
passData.distanceBuffer = builder.ReadTexture(distanceBuffer);
|
|
passData.noisyBuffer = builder.ReadTexture(noisyBuffer);
|
|
|
|
// Temporary buffers
|
|
passData.intermediateBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
|
|
{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Intermediate buffer" });
|
|
|
|
// Output buffer
|
|
passData.outputBuffer = builder.ReadWriteTexture(renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
|
|
{ colorFormat = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Denoised Buffer" }));
|
|
|
|
|
|
builder.SetRenderFunc(
|
|
(DiffuseShadowDenoiserSpherePassData data, RenderGraphContext ctx) =>
|
|
{
|
|
// Evaluate the dispatch parameters
|
|
int shadowTileSize = 8;
|
|
int numTilesX = (data.texWidth + (shadowTileSize - 1)) / shadowTileSize;
|
|
int numTilesY = (data.texHeight + (shadowTileSize - 1)) / shadowTileSize;
|
|
|
|
// Raise the distance based denoiser keyword
|
|
CoreUtils.SetKeyword(ctx.cmd, "DISTANCE_BASED_DENOISER", data.properties.distanceBasedDenoiser);
|
|
|
|
// Bind input uniforms for both dispatches
|
|
ctx.cmd.SetComputeIntParam(data.diffuseShadowDenoiserCS, HDShaderIDs._RaytracingTargetLight, data.properties.lightIndex);
|
|
switch(properties.lightType)
|
|
{
|
|
case GPULightType.Spot:
|
|
{
|
|
ctx.cmd.SetComputeFloatParam(data.diffuseShadowDenoiserCS, HDShaderIDs._RaytracingLightAngle, data.properties.lightConeAngle);
|
|
}
|
|
break;
|
|
case GPULightType.ProjectorPyramid:
|
|
case GPULightType.ProjectorBox:
|
|
{
|
|
ctx.cmd.SetComputeFloatParam(data.diffuseShadowDenoiserCS, HDShaderIDs._RaytracingLightSizeX, data.properties.lightSizeX);
|
|
ctx.cmd.SetComputeFloatParam(data.diffuseShadowDenoiserCS, HDShaderIDs._RaytracingLightSizeY, data.properties.lightSizeY);
|
|
}
|
|
break;
|
|
}
|
|
ctx.cmd.SetComputeFloatParam(data.diffuseShadowDenoiserCS, HDShaderIDs._RaytracingLightRadius, data.properties.lightRadius);
|
|
ctx.cmd.SetComputeIntParam(data.diffuseShadowDenoiserCS, HDShaderIDs._DenoiserFilterRadius, data.properties.kernelSize);
|
|
ctx.cmd.SetComputeVectorParam(data.diffuseShadowDenoiserCS, HDShaderIDs._SphereLightPosition, data.properties.lightPosition);
|
|
ctx.cmd.SetComputeFloatParam(data.diffuseShadowDenoiserCS, HDShaderIDs._CameraFOV, data.cameraFov);
|
|
|
|
// Bind Input Textures
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralHKernel, HDShaderIDs._DepthTexture, data.depthStencilBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralHKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralHKernel, HDShaderIDs._DenoiseInputTexture, data.noisyBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralHKernel, HDShaderIDs._StencilTexture, data.depthStencilBuffer, 0, RenderTextureSubElement.Stencil);
|
|
if (data.properties.distanceBasedDenoiser)
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralHKernel, HDShaderIDs._DistanceTexture, data.distanceBuffer);
|
|
|
|
// Bind output textures
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralHKernel, HDShaderIDs._DenoiseOutputTextureRW, data.intermediateBuffer);
|
|
|
|
// Do the Horizontal pass
|
|
ctx.cmd.DispatchCompute(data.diffuseShadowDenoiserCS, data.bilateralHKernel, numTilesX, numTilesY, data.viewCount);
|
|
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralVKernel, HDShaderIDs._DepthTexture, data.depthStencilBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralVKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralVKernel, HDShaderIDs._DenoiseInputTexture, data.intermediateBuffer);
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralVKernel, HDShaderIDs._StencilTexture, data.depthStencilBuffer, 0, RenderTextureSubElement.Stencil);
|
|
if (data.properties.distanceBasedDenoiser)
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralVKernel, HDShaderIDs._DistanceTexture, data.distanceBuffer);
|
|
|
|
// Bind output textures
|
|
ctx.cmd.SetComputeTextureParam(data.diffuseShadowDenoiserCS, data.bilateralVKernel, HDShaderIDs._DenoiseOutputTextureRW, data.outputBuffer);
|
|
|
|
// Do the Vertical pass
|
|
ctx.cmd.DispatchCompute(data.diffuseShadowDenoiserCS, data.bilateralVKernel, numTilesX, numTilesY, data.viewCount);
|
|
|
|
CoreUtils.SetKeyword(ctx.cmd, "DISTANCE_BASED_DENOISER", false);
|
|
});
|
|
return passData.outputBuffer;
|
|
}
|
|
}
|
|
}
|
|
}
|