Skip to content

[HDRP][Path Tracing] Added alpha channel to path traced results #3127

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 5 commits into from
Jan 18, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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 @@ -25,6 +25,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
- Fixed error in Depth Of Field near radius blur calculation (case 1306228).
- Fixed a reload bug when using objects from the scene in the lookdev (case 1300916).
- Fixed light gizmo showing shadow near plane when shadows are disabled.
- Fixed path tracing alpha channel support (case 1304187).

### Changed
- Change the source value for the ray tracing frame index iterator from m_FrameCount to the camera frame count (case 1301356).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ Rendering Buffer Format | Post-processing Buffer Format | Alpha Output
**R16G16B16A16** | **R11G11B10** | Alpha channel without post-processing (AlphaCopy)
**R16G16B16A16** | **R16G16B16A16** | Alpha channel with post-processing

Note that alpha output is also supported in [Path Tracing](Ray-Tracing-Path-Tracing.md).

## DoF and Alpha Output
Another case which might require post-processing of the alpha channel is for scenes that use Depth Of Field. In this case, if the alpha is not processed, compositing will result in a sharp cut-off of an object that should appear blurred. This is better is illustrated in the images below:

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,13 +51,15 @@ void KMain(uint3 dispatchThreadId : SV_DispatchThreadID)
UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z);
uint2 currentPixelCoord = dispatchThreadId.xy;

float exposureMultiplier = (_AccumulationNeedsExposure != 0) ? GetCurrentExposureMultiplier() : 1.0;
float4 exposureMultiplier;
exposureMultiplier.xyz = (_AccumulationNeedsExposure != 0) ? GetCurrentExposureMultiplier() : 1.0;
exposureMultiplier.w = 1.0;

// Have we reached max sampling?
uint sampleCount = _AccumulationFrameIndex;
if (sampleCount >= _AccumulationNumSamples)
{
_CameraColorTextureRW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(_AccumulatedFrameTexture[COORD_TEXTURE2D_X(currentPixelCoord)].xyz * exposureMultiplier, 1.0);
_CameraColorTextureRW[COORD_TEXTURE2D_X(currentPixelCoord)] = _AccumulatedFrameTexture[COORD_TEXTURE2D_X(currentPixelCoord)] * exposureMultiplier;
}
else
{
Expand All @@ -68,16 +70,16 @@ void KMain(uint3 dispatchThreadId : SV_DispatchThreadID)
#endif

if (sampleCount++)
color.xyz = (_AccumulatedFrameTexture[COORD_TEXTURE2D_X(currentPixelCoord)].xyz * _AccumulationWeights.y + _AccumulationWeights.x * color.xyz) * _AccumulationWeights.z;
color = (_AccumulatedFrameTexture[COORD_TEXTURE2D_X(currentPixelCoord)] * _AccumulationWeights.y + _AccumulationWeights.x * color) * _AccumulationWeights.z;

_AccumulatedFrameTexture[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(color.xyz, 1.0);
_AccumulatedFrameTexture[COORD_TEXTURE2D_X(currentPixelCoord)] = color;

// Apply exposure modifier
color *= exposureMultiplier;

// Add a little convergence cue to our result
AddConvergenceCue(currentPixelCoord, sampleCount, color.xyz);

_CameraColorTextureRW[COORD_TEXTURE2D_X(currentPixelCoord)] = float4(color.xyz, 1.0);
_CameraColorTextureRW[COORD_TEXTURE2D_X(currentPixelCoord)] = color;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,15 @@
// Structure that defines the current state of the intersection, for path tracing
struct PathIntersection
{
// t as in: O + t*D = H (i.e. distance between O and H, if D is normalized)
float t;
// Resulting value (often color) of the ray
float3 value;
// Resulting alpha (camera rays only)
float alpha;
// Cone representation of the ray
RayCone cone;
// The remaining available depth for the current Ray
// The remaining available depth for the current ray
uint remainingDepth;
// Pixel coordinate from which the initial ray was launched
uint2 pixelCoord;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
// Input(s)
float4x4 _PixelCoordToViewDirWS;
int _RaytracingCameraSkyEnabled;
float3 _RaytracingCameraClearColor;
float4 _RaytracingCameraClearColor;

// DoF related parameters
float4 _PathTracedDoFConstants; // x: aperture radius, y: focus distance, zw: unused
Expand All @@ -36,9 +36,9 @@ RWTexture2D<float4> _RadianceTexture;
[shader("miss")]
void MissCamera(inout PathIntersection pathIntersection : SV_RayPayload)
{
// If the _RaytracingCameraClearColor content is positive, we override the camera sky display with a bg color
pathIntersection.value = _EnvLightSkyEnabled && _RaytracingCameraSkyEnabled ?
SampleSkyTexture(WorldRayDirection(), 0.0, 0).xyz : _RaytracingCameraClearColor * GetInverseCurrentExposureMultiplier();
bool skyEnabled = _EnvLightSkyEnabled && _RaytracingCameraSkyEnabled;
pathIntersection.value = skyEnabled ? SampleSkyTexture(WorldRayDirection(), 0.0, 0).xyz : _RaytracingCameraClearColor.xyz * GetInverseCurrentExposureMultiplier();
pathIntersection.alpha = skyEnabled ? 1.0 : _RaytracingCameraClearColor.w;

ApplyFogAttenuation(WorldRayOrigin(), WorldRayDirection(), pathIntersection.value);

Expand Down Expand Up @@ -137,6 +137,7 @@ void RayGen()
// Create and init the PathIntersection structure for this
PathIntersection pathIntersection;
pathIntersection.value = 1.0;
pathIntersection.alpha = 1.0;
pathIntersection.remainingDepth = _RaytracingMaxRecursion;
pathIntersection.pixelCoord = currentPixelCoord;
pathIntersection.maxRoughness = 0.0;
Expand All @@ -148,7 +149,7 @@ void RayGen()
// Evaluate the ray intersection
TraceRay(_RaytracingAccelerationStructure, RAY_FLAG_CULL_BACK_FACING_TRIANGLES, RAYTRACINGRENDERERFLAG_PATH_TRACING, 0, 1, 0, rayDescriptor, pathIntersection);

_RadianceTexture[currentPixelCoord] = float4(pathIntersection.value, 1.0);
_RadianceTexture[currentPixelCoord] = float4(pathIntersection.value, pathIntersection.alpha);
}

// This should never be called, return magenta just in case
Expand Down