Skip to content

[HDRP][Path Tracing] Added proper support for interleaved tiling #5953

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Oct 20, 2021
1 change: 1 addition & 0 deletions com.unity.render-pipelines.high-definition/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixed minor performance issues in SSGI (case 1367144).
- Fixed scaling issues with dynamic resolution and the CustomPassSampleCameraColor function.
- Fixed compatibility message not displayed correctly when switching platforms.
- Fixed support for interleaved tiling in path tracing.

### Changed
- Use RayTracingAccelerationStructure.CullInstances to filter Renderers and populate the acceleration structure with ray tracing instances for improved CPU performance on the main thread.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -589,8 +589,9 @@ static class HDShaderIDs
public static readonly string _RaytracingAccelerationStructureName = "_RaytracingAccelerationStructure";

// Path tracing variables
public static readonly int _PathTracedDoFConstants = Shader.PropertyToID("_PathTracedDoFConstants");
public static readonly int _InvViewportScaleBias = Shader.PropertyToID("_InvViewportScaleBias");
public static readonly int _PathTracingDoFParameters = Shader.PropertyToID("_PathTracingDoFParameters");
public static readonly int _PathTracingTilingParameters = Shader.PropertyToID("_PathTracingTilingParameters");

// Light Cluster
public static readonly int _LightDatasRT = Shader.PropertyToID("_LightDatasRT");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ public sealed class PathTracing : VolumeComponent
[Tooltip("Defines the maximum, post-exposed luminance computed for indirect path segments. Lower values help against noise and fireflies (very bright pixels), but introduce bias by darkening the overall result. Increase this value if your image looks too dark.")]
public MinFloatParameter maximumIntensity = new MinFloatParameter(10f, 0f);

/// <summary>
/// Defines the number of tiles (X: width, Y: height) and the indices of the current tile (Z: i in [0, width[, W: j in [0, height[) for interleaved tiled rendering.
/// </summary>
[Tooltip("Defines the number of tiles (X: width, Y: height) and the indices of the current tile (Z: i in [0, width[, W: j in [0, height[) for interleaved tiled rendering.")]
public Vector4Parameter tilingParameters = new Vector4Parameter(new Vector4(1, 1, 0, 0));

/// <summary>
/// Default constructor for the path tracing volume component.
/// </summary>
Expand Down Expand Up @@ -253,6 +259,7 @@ class RenderPathTracingData
public Texture skyReflection;
public Matrix4x4 pixelCoordToViewDirWS;
public Vector4 dofParameters;
public Vector4 tilingParameters;
public int width, height;
public RayTracingAccelerationStructure accelerationStructure;
public HDRaytracingLightCluster lightCluster;
Expand All @@ -272,6 +279,7 @@ TextureHandle RenderPathTracing(RenderGraph renderGraph, HDCamera hdCamera, in C
passData.skyReflection = m_SkyManager.GetSkyReflection(hdCamera);
passData.pixelCoordToViewDirWS = hdCamera.mainViewConstants.pixelCoordToViewDirWS;
passData.dofParameters = ComputeDoFConstants(hdCamera, m_PathTracingSettings);
passData.tilingParameters = m_PathTracingSettings.tilingParameters.value;
passData.width = hdCamera.actualWidth;
passData.height = hdCamera.actualHeight;
passData.accelerationStructure = RequestAccelerationStructure();
Expand Down Expand Up @@ -319,7 +327,8 @@ TextureHandle RenderPathTracing(RenderGraph renderGraph, HDCamera hdCamera, in C
// Additional data for path tracing
ctx.cmd.SetRayTracingTextureParam(data.pathTracingShader, HDShaderIDs._FrameTexture, data.output);
ctx.cmd.SetRayTracingMatrixParam(data.pathTracingShader, HDShaderIDs._PixelCoordToViewDirWS, data.pixelCoordToViewDirWS);
ctx.cmd.SetRayTracingVectorParam(data.pathTracingShader, HDShaderIDs._PathTracedDoFConstants, data.dofParameters);
ctx.cmd.SetRayTracingVectorParam(data.pathTracingShader, HDShaderIDs._PathTracingDoFParameters, data.dofParameters);
ctx.cmd.SetRayTracingVectorParam(data.pathTracingShader, HDShaderIDs._PathTracingTilingParameters, data.tilingParameters);

// Run the computation
ctx.cmd.DispatchRays(data.pathTracingShader, "RayGen", (uint)data.width, (uint)data.height, 1);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,13 +27,12 @@ float4x4 _PixelCoordToViewDirWS;
int _RaytracingCameraSkyEnabled;
float4 _RaytracingCameraClearColor;
TEXTURE2D_X(_SkyCameraTexture);
float4 _PathTracingDoFParameters; // x: aperture radius, y: focus distance, zw: unused
float4 _PathTracingTilingParameters; // xy: tile count, zw: current tile index

// Output(s)
RW_TEXTURE2D_X(float4, _FrameTexture);

// DoF related parameters
float4 _PathTracedDoFConstants; // x: aperture radius, y: focus distance, zw: unused

[shader("miss")]
void MissCamera(inout PathIntersection pathIntersection : SV_RayPayload)
{
Expand Down Expand Up @@ -92,19 +91,17 @@ void MissMaterial(inout PathIntersection pathIntersection : SV_RayPayload)

void ApplyDepthOfField(uint2 pixelCoord, float dotDirection, inout float3 origin, inout float3 direction)
{
float apertureRadius = _PathTracedDoFConstants.x;

if (apertureRadius <= 0.0)
// Check aperture radius
if (_PathTracingDoFParameters.x <= 0.0)
return;

// Sample the lens aperture using the next available dimensions
// (we use 40 for path tracing, 2 for sub-pixel jittering, 64 for SSS -> 106, 107)
float2 uv = apertureRadius * SampleDiskUniform(GetSample(pixelCoord, _RaytracingSampleIndex, 106),
GetSample(pixelCoord, _RaytracingSampleIndex, 107));
float2 uv = _PathTracingDoFParameters.x * SampleDiskUniform(GetSample(pixelCoord, _RaytracingSampleIndex, 106),
GetSample(pixelCoord, _RaytracingSampleIndex, 107));

// Compute the focus point by intersecting the pinhole ray with the focus plane
float focusDistance = _PathTracedDoFConstants.y;
float t = focusDistance / dotDirection;
float t = _PathTracingDoFParameters.y / dotDirection;
float3 focusPoint = origin + t * direction;

// Compute the new ray origin (_ViewMatrix[0] = right, _ViewMatrix[1] = up)
Expand All @@ -120,10 +117,15 @@ void RayGen()
// Get the current pixel coordinates
uint2 pixelCoord = DispatchRaysIndex().xy;

// Get the current tile coordinates (for interleaved tiling) and update pixel coordinates accordingly
uint2 tileCount = uint2(_PathTracingTilingParameters.xy);
uint2 tileIndex = uint2(_PathTracingTilingParameters.zw);
uint2 tiledPixelCoord = pixelCoord * tileCount + tileIndex;

// Jitter them (we use 4x10 dimensions of our sequence during path tracing atm, so pick the next available ones)
float4 jitteredPixelCoord = float4(pixelCoord, 1.0, 1.0);
jitteredPixelCoord.x += GetSample(pixelCoord, _RaytracingSampleIndex, 40);
jitteredPixelCoord.y += GetSample(pixelCoord, _RaytracingSampleIndex, 41);
jitteredPixelCoord.x += GetSample(tiledPixelCoord, _RaytracingSampleIndex, 40) / tileCount.x;
jitteredPixelCoord.y += GetSample(tiledPixelCoord, _RaytracingSampleIndex, 41) / tileCount.y;

// Create the ray descriptor for this pixel
RayDesc ray;
Expand All @@ -143,7 +145,7 @@ void RayGen()
float dotDirection = dot(cameraDirection, ray.Direction);
ray.TMin /= dotDirection;

ApplyDepthOfField(pixelCoord, dotDirection, ray.Origin, ray.Direction);
ApplyDepthOfField(tiledPixelCoord, dotDirection, ray.Origin, ray.Direction);
}
else // Orthographic projection
{
Expand All @@ -156,16 +158,16 @@ void RayGen()
ray.Direction = cameraDirection;
}

// Create and init the PathIntersection structure for this
// Create and init the PathIntersection structure for this pixel
PathIntersection pathIntersection;
pathIntersection.value = 1.0;
pathIntersection.alpha = 1.0;
pathIntersection.remainingDepth = _RaytracingMaxRecursion;
pathIntersection.pixelCoord = pixelCoord;
pathIntersection.pixelCoord = tiledPixelCoord;
pathIntersection.maxRoughness = 0.0;

// In order to achieve filtering for the textures, we need to compute the spread angle of the pixel
pathIntersection.cone.spreadAngle = _RaytracingPixelSpreadAngle;
pathIntersection.cone.spreadAngle = _RaytracingPixelSpreadAngle / min(tileCount.x, tileCount.y);
pathIntersection.cone.width = 0.0;

// Evaluate the ray intersection
Expand Down