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.
 
 
 
 

445 lines
26 KiB

using UnityEngine;
using UnityEngine.Experimental.Rendering;
using System.Collections.Generic;
using UnityEngine.Rendering.RenderGraphModule;
namespace UnityEngine.Rendering.HighDefinition
{
public partial class HDRenderPipeline
{
// Ray binning buffers
ComputeBuffer m_RayBinResult = null;
ComputeBuffer m_RayBinSizeResult = null;
// The set of ray tracing shader names
const string m_RayGenGBuffer = "RayGenGBuffer";
const string m_RayGenGBufferHalfRes = "RayGenGBufferHalfRes";
const string m_RayGenGBufferBinned = "RayGenGBufferBinned";
const string m_RayGenGBufferHalfResBinned = "RayGenGBufferHalfResBinned";
const string m_MissShaderNameGBuffer = "MissShaderGBuffer";
// Resolution of the binning tile
const int binningTileSize = 16;
void InitRaytracingDeferred()
{
m_RayBinResult = new ComputeBuffer(1, sizeof(uint));
m_RayBinSizeResult = new ComputeBuffer(1, sizeof(uint));
}
void ReleaseRayTracingDeferred()
{
CoreUtils.SafeRelease(m_RayBinResult);
CoreUtils.SafeRelease(m_RayBinSizeResult);
}
void CheckBinningBuffersSize(HDCamera hdCamera)
{
// Grab the number of view we'll need to support
int numViews = hdCamera.viewCount;
// Evaluate the number of tiles
int numTilesRayBinX = (hdCamera.actualWidth + (binningTileSize - 1)) / binningTileSize;
int numTilesRayBinY = (hdCamera.actualHeight + (binningTileSize - 1)) / binningTileSize;
int minimalTileBufferSize = numViews * numTilesRayBinX * numTilesRayBinY;
// Evaluate the global size
int bufferSizeX = numTilesRayBinX * binningTileSize;
int bufferSizeY = numTilesRayBinY * binningTileSize;
int minimalBufferSize = numViews * bufferSizeX * bufferSizeY;
// Resize the binning buffers if required
if (minimalBufferSize > m_RayBinResult.count)
{
if (m_RayBinResult != null)
{
CoreUtils.SafeRelease(m_RayBinResult);
CoreUtils.SafeRelease(m_RayBinSizeResult);
m_RayBinResult = null;
m_RayBinSizeResult = null;
}
if (minimalBufferSize > 0)
{
m_RayBinResult = new ComputeBuffer(minimalBufferSize, sizeof(uint));
m_RayBinSizeResult = new ComputeBuffer(minimalTileBufferSize, sizeof(uint));
}
}
}
// The set of parameters that define our ray tracing deferred lighting pass
struct DeferredLightingRTParameters
{
// Generic attributes
public bool rayBinning;
public LayerMask layerMask;
public bool diffuseLightingOnly;
public bool halfResolution;
public int rayCountType;
public float lodBias;
public int rayMiss;
public int lastBounceFallbackHierarchy;
// Ray marching attributes
public bool mixedTracing;
public int raySteps;
public float nearClipPlane;
public float farClipPlane;
public bool transparent;
// Camera data
public int width;
public int height;
public int viewCount;
// Compute buffers
public ComputeBuffer rayBinResult;
public ComputeBuffer rayBinSizeResult;
public ComputeBuffer mipChainBuffer;
public RayTracingAccelerationStructure accelerationStructure;
public HDRaytracingLightCluster lightCluster;
// Shaders
public ComputeShader rayMarchingCS;
public RayTracingShader gBufferRaytracingRT;
public ComputeShader deferredRaytracingCS;
public ComputeShader rayBinningCS;
public ShaderVariablesRaytracing raytracingCB;
}
class DeferredLightingRTRPassData
{
public DeferredLightingRTParameters parameters;
// Prepass textures
public TextureHandle depthPyramid;
public TextureHandle depthStencilBuffer;
public TextureHandle normalBuffer;
public TextureHandle ssgbuffer0;
public TextureHandle ssgbuffer1;
public TextureHandle ssgbuffer2;
public TextureHandle ssgbuffer3;
// Input textures
public TextureHandle directionBuffer;
public TextureHandle renderingLayersTexture;
// Intermediate textures
public TextureHandle gbuffer0;
public TextureHandle gbuffer1;
public TextureHandle gbuffer2;
public TextureHandle gbuffer3;
public TextureHandle tmpDistanceBuffer;
// Output textures
public TextureHandle litBuffer;
public TextureHandle distanceBuffer;
public TextureHandle rayCountTexture;
// Data textures
public Texture skyTexture;
public bool enableDecals;
}
static void BinRays(CommandBuffer cmd, in DeferredLightingRTParameters config, RTHandle directionBuffer, int texWidth, int texHeight)
{
// We need to go through the ray binning pass (if required)
int currentKernel = config.rayBinningCS.FindKernel(config.halfResolution ? "RayBinningHalf" : "RayBinning");
// Evaluate the dispatch parameters
int numTilesRayBinX = (texWidth + (binningTileSize - 1)) / binningTileSize;
int numTilesRayBinY = (texHeight + (binningTileSize - 1)) / binningTileSize;
int bufferSizeX = numTilesRayBinX * binningTileSize;
int bufferSizeY = numTilesRayBinY * binningTileSize;
// Bind the resources
cmd.SetComputeTextureParam(config.rayBinningCS, currentKernel, HDShaderIDs._RaytracingDirectionBuffer, directionBuffer);
cmd.SetComputeBufferParam(config.rayBinningCS, currentKernel, HDShaderIDs._RayBinResult, config.rayBinResult);
cmd.SetComputeBufferParam(config.rayBinningCS, currentKernel, HDShaderIDs._RayBinSizeResult, config.rayBinSizeResult);
cmd.SetComputeIntParam(config.rayBinningCS, HDShaderIDs._RayBinTileCountX, numTilesRayBinX);
// Inject the data for the additional views
cmd.SetComputeIntParam(config.rayBinningCS, HDShaderIDs._RayBinViewOffset, bufferSizeX * bufferSizeY);
cmd.SetComputeIntParam(config.rayBinningCS, HDShaderIDs._RayBinTileViewOffset, numTilesRayBinX * numTilesRayBinY);
// Run the binning
cmd.DispatchCompute(config.rayBinningCS, currentKernel, numTilesRayBinX, numTilesRayBinY, config.viewCount);
}
static void RayMarchGBuffer(CommandBuffer cmd, in DeferredLightingRTRPassData data, int texWidth, int texHeight)
{
// Now let's do the deferred shading pass on the samples
int marchingKernel = data.parameters.rayMarchingCS.FindKernel(data.parameters.halfResolution ? "RayMarchHalfKernel" : "RayMarchKernel");
// Evaluate the dispatch parameters
int numTilesRayBinX = (texWidth + (8 - 1)) / 8;
int numTilesRayBinY = (texHeight + (8 - 1)) / 8;
// Prepass textures
if (data.parameters.transparent)
{
// Use the transparent pre-pass depth for ray start position, and do not filter using stencil
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._InputDepthTexture, data.depthStencilBuffer, 0, RenderTextureSubElement.Depth);
cmd.SetComputeIntParam(data.parameters.rayMarchingCS, HDShaderIDs._DeferredStencilBit, 0);
}
else
{
// Use the depth pyramid for ray start position (since it is already bound for hit testing), filter pixels using stencil
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._InputDepthTexture, data.depthPyramid);
cmd.SetComputeIntParam(data.parameters.rayMarchingCS, HDShaderIDs._DeferredStencilBit, (int)StencilUsage.RequiresDeferredLighting);
}
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._DepthTexture, data.depthPyramid);
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer);
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._StencilTexture, data.depthStencilBuffer, 0, RenderTextureSubElement.Stencil);
cmd.SetComputeBufferParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._DepthPyramidMipLevelOffsets, data.parameters.mipChainBuffer);
// Bind the input parameters
float n = data.parameters.nearClipPlane;
float f = data.parameters.farClipPlane;
float thicknessScale = 1.0f / (1.0f + 0.01f);
float thicknessBias = -n / (f - n) * (0.01f * thicknessScale);
cmd.SetComputeFloatParam(data.parameters.rayMarchingCS, HDShaderIDs._RayMarchingThicknessScale, thicknessScale);
cmd.SetComputeFloatParam(data.parameters.rayMarchingCS, HDShaderIDs._RayMarchingThicknessBias, thicknessBias);
cmd.SetComputeIntParam(data.parameters.rayMarchingCS, HDShaderIDs._RayMarchingSteps, data.parameters.raySteps);
cmd.SetComputeIntParam(data.parameters.rayMarchingCS, HDShaderIDs._RayMarchingReflectSky, 0);
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._RaytracingDirectionBuffer, data.directionBuffer);
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._GBufferTexture[0], data.ssgbuffer0);
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._GBufferTexture[1], data.ssgbuffer1);
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._GBufferTexture[2], data.ssgbuffer2);
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._GBufferTexture[3], data.ssgbuffer3);
// Bind the output textures
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._GBufferTextureRW[0], data.gbuffer0);
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._GBufferTextureRW[1], data.gbuffer1);
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._GBufferTextureRW[2], data.gbuffer2);
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._GBufferTextureRW[3], data.gbuffer3);
cmd.SetComputeTextureParam(data.parameters.rayMarchingCS, marchingKernel, HDShaderIDs._RaytracingDistanceBuffer, data.tmpDistanceBuffer);
// Run the ray marching
cmd.DispatchCompute(data.parameters.rayMarchingCS, marchingKernel, numTilesRayBinX, numTilesRayBinY, data.parameters.viewCount);
}
struct RayTracingDefferedLightLoopOutput
{
public TextureHandle lightingBuffer;
public TextureHandle distanceBuffer;
}
RayTracingDefferedLightLoopOutput DeferredLightingRT(RenderGraph renderGraph,
HDCamera hdCamera,
in DeferredLightingRTParameters parameters,
TextureHandle directionBuffer,
in PrepassOutput prepassOutput,
Texture skyTexture,
TextureHandle rayCountTexture)
{
RayTracingDefferedLightLoopOutput output = new RayTracingDefferedLightLoopOutput();
using (var builder = renderGraph.AddUnsafePass<DeferredLightingRTRPassData>("Deferred Lighting Ray Tracing", out var passData, ProfilingSampler.Get(HDProfileId.RaytracingDeferredLighting)))
{
passData.parameters = parameters;
// Input Buffers
passData.directionBuffer = directionBuffer;
builder.UseTexture(passData.directionBuffer, AccessFlags.Read);
passData.depthStencilBuffer = prepassOutput.depthBuffer;
builder.UseTexture(passData.depthStencilBuffer, AccessFlags.Read);
passData.depthPyramid = prepassOutput.depthPyramidTexture;
builder.UseTexture(passData.depthPyramid, AccessFlags.Read);
passData.normalBuffer = prepassOutput.normalBuffer;
builder.UseTexture(passData.normalBuffer, AccessFlags.Read);
passData.renderingLayersTexture = renderGraph.defaultResources.whiteTextureXR;
builder.UseTexture(passData.renderingLayersTexture, AccessFlags.Read);
if (passData.parameters.mixedTracing)
{
passData.ssgbuffer0 = prepassOutput.gbuffer.mrt[0];
passData.ssgbuffer1 = prepassOutput.gbuffer.mrt[1];
passData.ssgbuffer2 = prepassOutput.gbuffer.mrt[2];
passData.ssgbuffer3 = prepassOutput.gbuffer.mrt[3];
}
else
{
passData.ssgbuffer0 = renderGraph.defaultResources.blackTextureXR;
passData.ssgbuffer1 = renderGraph.defaultResources.blackTextureXR;
passData.ssgbuffer2 = renderGraph.defaultResources.blackTextureXR;
passData.ssgbuffer3 = renderGraph.defaultResources.blackTextureXR;
}
builder.UseTexture(passData.ssgbuffer0, AccessFlags.Read);
builder.UseTexture(passData.ssgbuffer1, AccessFlags.Read);
builder.UseTexture(passData.ssgbuffer2, AccessFlags.Read);
builder.UseTexture(passData.ssgbuffer3, AccessFlags.Read);
passData.skyTexture = skyTexture;
// Temporary buffers
passData.gbuffer0 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
{ format = GraphicsFormat.R8G8B8A8_SRGB, enableRandomWrite = true, name = "GBuffer0" });
passData.gbuffer1 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
{ format = GraphicsFormat.R8G8B8A8_UNorm, enableRandomWrite = true, name = "GBuffer1" });
passData.gbuffer2 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
{ format = GraphicsFormat.R8G8B8A8_UNorm, enableRandomWrite = true, name = "GBuffer2" });
passData.gbuffer3 = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
{ format = Builtin.GetLightingBufferFormat(), enableRandomWrite = true, name = "GBuffer3" });
passData.tmpDistanceBuffer = builder.CreateTransientTexture(new TextureDesc(Vector2.one, true, true)
{ format = GraphicsFormat.R32_SFloat, enableRandomWrite = true, name = "TMP Distance Buffer" });
// Output buffers
passData.rayCountTexture = rayCountTexture;
builder.UseTexture(passData.rayCountTexture, AccessFlags.ReadWrite);
passData.litBuffer = renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
{ format = GraphicsFormat.R16G16B16A16_SFloat, enableRandomWrite = true, name = "Deferred Lighting Result" });
builder.UseTexture(passData.litBuffer, AccessFlags.Write);
passData.distanceBuffer = renderGraph.CreateTexture(new TextureDesc(Vector2.one, true, true)
{ format = GraphicsFormat.R32_SFloat, enableRandomWrite = true, name = "Distance Buffer" });
builder.UseTexture(passData.distanceBuffer, AccessFlags.Write);
passData.enableDecals = hdCamera.frameSettings.IsEnabled(FrameSettingsField.Decals);
builder.SetRenderFunc(
(DeferredLightingRTRPassData data, UnsafeGraphContext ctx) =>
{
var natCmd = CommandBufferHelpers.GetNativeCommandBuffer(ctx.cmd);
// Compute the input texture dimension
int texWidth = data.parameters.width;
int texHeight = data.parameters.height;
if (data.parameters.halfResolution)
{
// Given that the up-sampling if half resolution potentially needs the last/extra pixel (if the resolution is odd), we need to make sure
// that the ray tracing and lighting is evaluated with that in mind.
texWidth = (texWidth + 1) / 2;
texHeight = (texHeight + 1) / 2;
}
// Inject the global parameters
ConstantBuffer.PushGlobal(natCmd, data.parameters.raytracingCB, HDShaderIDs._ShaderVariablesRaytracing);
// If mixed ray tracing was enabled for this pass, we need to try to resolve as many pixels as possible
// using the depth buffer ray marching
if (data.parameters.mixedTracing)
{
RayMarchGBuffer(natCmd, data, texWidth, texHeight);
}
if (data.parameters.rayBinning)
{
BinRays(natCmd, data.parameters, data.directionBuffer, texWidth, texHeight);
}
// Inject the global parameters
data.parameters.raytracingCB._RayTracingLodBias = data.parameters.lodBias;
ConstantBuffer.PushGlobal(natCmd, data.parameters.raytracingCB, HDShaderIDs._ShaderVariablesRaytracing);
// Define the shader pass to use for the reflection pass
natCmd.SetRayTracingShaderPass(data.parameters.gBufferRaytracingRT, "GBufferDXR");
if (data.parameters.rayBinning)
{
int numTilesRayBinX = (texWidth + (binningTileSize - 1)) / binningTileSize;
natCmd.SetGlobalBuffer(HDShaderIDs._RayBinResult, data.parameters.rayBinResult);
natCmd.SetGlobalBuffer(HDShaderIDs._RayBinSizeResult, data.parameters.rayBinSizeResult);
natCmd.SetRayTracingIntParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._RayBinTileCountX, numTilesRayBinX);
}
// Set the acceleration structure for the pass
natCmd.SetRayTracingAccelerationStructure(data.parameters.gBufferRaytracingRT, HDShaderIDs._RaytracingAccelerationStructureName, data.parameters.accelerationStructure);
// Set ray count texture
natCmd.SetRayTracingIntParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._RayCountType, data.parameters.rayCountType);
natCmd.SetRayTracingTextureParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._RayCountTexture, data.rayCountTexture);
// Bind all input parameter
natCmd.SetRayTracingIntParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._RayTracingLayerMask, data.parameters.layerMask);
natCmd.SetRayTracingTextureParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._DepthTexture, data.depthStencilBuffer);
natCmd.SetRayTracingTextureParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._NormalBufferTexture, data.normalBuffer);
natCmd.SetRayTracingTextureParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._RaytracingDirectionBuffer, data.directionBuffer);
natCmd.SetRayTracingIntParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._RaytracingHalfResolution, data.parameters.halfResolution ? 1 : 0);
// Bind the output textures
natCmd.SetRayTracingTextureParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[0], data.gbuffer0);
natCmd.SetRayTracingTextureParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[1], data.gbuffer1);
natCmd.SetRayTracingTextureParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[2], data.gbuffer2);
natCmd.SetRayTracingTextureParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._GBufferTextureRW[3], data.gbuffer3);
natCmd.SetRayTracingTextureParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._RaytracingDistanceBuffer, data.tmpDistanceBuffer);
// Compute the actual resolution that is needed base on the resolution
uint widthResolution = (uint)data.parameters.width;
uint heightResolution = (uint)data.parameters.height;
// Include the sky if required
natCmd.SetRayTracingTextureParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._SkyTexture, data.skyTexture);
// Only compute diffuse lighting if required
CoreUtils.SetKeyword(natCmd, "MINIMAL_GBUFFER", data.parameters.diffuseLightingOnly);
if (data.enableDecals)
{
DecalSystem.instance.SetAtlas(natCmd);
data.parameters.lightCluster.BindLightClusterData(natCmd);
}
if (data.parameters.rayBinning)
{
// Evaluate the dispatch data.parameters
int numTilesRayBinX = (texWidth + (binningTileSize - 1)) / binningTileSize;
int numTilesRayBinY = (texHeight + (binningTileSize - 1)) / binningTileSize;
int bufferSizeX = numTilesRayBinX * binningTileSize;
int bufferSizeY = numTilesRayBinY * binningTileSize;
natCmd.SetRayTracingIntParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._BufferSizeX, bufferSizeX);
// Inject the data for the additional views
natCmd.SetRayTracingIntParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._RayBinViewOffset, bufferSizeX * bufferSizeY);
natCmd.SetRayTracingIntParam(data.parameters.gBufferRaytracingRT, HDShaderIDs._RayBinTileViewOffset, numTilesRayBinX * numTilesRayBinY);
// A really nice tip is to dispatch the rays as a 1D array instead of 2D, the performance difference has been measured.
uint dispatchSize = (uint)(bufferSizeX * bufferSizeY);
natCmd.DispatchRays(data.parameters.gBufferRaytracingRT, m_RayGenGBufferBinned, dispatchSize, 1, (uint)data.parameters.viewCount, null);
}
else
{
natCmd.DispatchRays(data.parameters.gBufferRaytracingRT, m_RayGenGBuffer, widthResolution, heightResolution, (uint)data.parameters.viewCount, null);
}
CoreUtils.SetKeyword(natCmd, "MINIMAL_GBUFFER", false);
// Now let's do the deferred shading pass on the samples
int currentKernel = data.parameters.deferredRaytracingCS.FindKernel(data.parameters.halfResolution ? "RaytracingDeferredHalf" : "RaytracingDeferred");
// Bind the lightLoop data
data.parameters.lightCluster.BindLightClusterData(natCmd);
// Bind the input textures
natCmd.SetComputeTextureParam(data.parameters.deferredRaytracingCS, currentKernel, HDShaderIDs._DepthTexture, data.depthStencilBuffer);
natCmd.SetComputeTextureParam(data.parameters.deferredRaytracingCS, currentKernel, HDShaderIDs._NormalBufferTexture, data.normalBuffer);
natCmd.SetComputeTextureParam(data.parameters.deferredRaytracingCS, currentKernel, HDShaderIDs._RaytracingDirectionBuffer, data.directionBuffer);
natCmd.SetComputeTextureParam(data.parameters.deferredRaytracingCS, currentKernel, HDShaderIDs._RaytracingDistanceBuffer, data.tmpDistanceBuffer);
natCmd.SetComputeTextureParam(data.parameters.deferredRaytracingCS, currentKernel, HDShaderIDs._GBufferTexture[0], data.gbuffer0);
natCmd.SetComputeTextureParam(data.parameters.deferredRaytracingCS, currentKernel, HDShaderIDs._GBufferTexture[1], data.gbuffer1);
natCmd.SetComputeTextureParam(data.parameters.deferredRaytracingCS, currentKernel, HDShaderIDs._GBufferTexture[2], data.gbuffer2);
natCmd.SetComputeTextureParam(data.parameters.deferredRaytracingCS, currentKernel, HDShaderIDs._GBufferTexture[3], data.gbuffer3);
natCmd.SetComputeTextureParam(data.parameters.deferredRaytracingCS, currentKernel, HDShaderIDs._RenderingLayersTexture, data.renderingLayersTexture);
// Bind the output texture
natCmd.SetComputeTextureParam(data.parameters.deferredRaytracingCS, currentKernel, HDShaderIDs._RaytracingLitBufferRW, data.litBuffer);
natCmd.SetComputeTextureParam(data.parameters.deferredRaytracingCS, currentKernel, HDShaderIDs._RaytracingDistanceBufferRW, data.distanceBuffer);
// Evaluate the dispatch parameters
int areaTileSize = 8;
int numTilesXHR = (texWidth + (areaTileSize - 1)) / areaTileSize;
int numTilesYHR = (texHeight + (areaTileSize - 1)) / areaTileSize;
// Compute the texture
natCmd.DispatchCompute(data.parameters.deferredRaytracingCS, currentKernel, numTilesXHR, numTilesYHR, data.parameters.viewCount);
});
// Output the two buffers we need
output.lightingBuffer = passData.litBuffer;
output.distanceBuffer = passData.distanceBuffer;
return output;
}
}
}
}