2021-09-09 20:42:29 -04:00

143 lines
4.7 KiB
Plaintext

#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/GTAOCommon.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Material/NormalBuffer.hlsl"
// TODO: This pass really could really use some quality improvement.
#pragma kernel SpatialDenoise
#pragma multi_compile _ TO_TEMPORAL
TEXTURE2D_X(_AOPackedData);
#ifdef TO_TEMPORAL
RW_TEXTURE2D_X(float, _AOPackedBlurred);
#else
RW_TEXTURE2D_X(float, _OcclusionTexture);
#endif
#define DEBUG_VISUALIZE_BILATERAL_WEIGHTS 0
#define BILATERAL_EPSILON 0.01
float BilateralWeight(float sampleDepth, float linearCentralDepth)
{
float linearSample = LinearEyeDepth(sampleDepth, _ZBufferParams);
float delta = abs(linearSample - linearCentralDepth);
float w = saturate(1.0f - (_AOSpatialBilateralAggressiveness * delta + BILATERAL_EPSILON));
return w;
}
float Blur(float2 centralPos, out float centralDepth, out float centralAO)
{
float4 UnpackedAOs, UnpackedDepths;
float2 UV = ClampAndScaleUVForBilinear((centralPos + float2(0.0, 0.0)) * _AOBufferSize.zw, _AOBufferSize.zw);
GatherAOData(_AOPackedData, UV, UnpackedAOs, UnpackedDepths);
centralDepth = UnpackedDepths.y;
float linearCentralDepth = LinearEyeDepth(centralDepth, _ZBufferParams);
centralAO = UnpackedAOs.y;
float total = UnpackedAOs.y;
float totalWeight = 1;
// This manual unrolling is horrible looking, but I found it hard to please the PS4 compiler otherwise. TODO: Make this nicer.
// First set of gathered data.
float weight = BilateralWeight(UnpackedDepths.x, linearCentralDepth);
total += weight * UnpackedAOs.x;
totalWeight += weight;
weight = BilateralWeight(UnpackedDepths.z, linearCentralDepth);
total += weight * UnpackedAOs.z;
totalWeight += weight;
weight = BilateralWeight(UnpackedDepths.w, linearCentralDepth);
total += weight * UnpackedAOs.w;
totalWeight += weight;
// Second set of gathered data.
UV = ClampAndScaleUVForBilinear((centralPos + float2(2.0, 0.0)) * _AOBufferSize.zw, _AOBufferSize.zw);
GatherAOData(_AOPackedData, UV, UnpackedAOs, UnpackedDepths);
weight = BilateralWeight(UnpackedDepths.x, linearCentralDepth);
total += weight * UnpackedAOs.x;
totalWeight += weight;
weight = BilateralWeight(UnpackedDepths.y, linearCentralDepth);
total += weight * UnpackedAOs.y;
totalWeight += weight;
weight = BilateralWeight(UnpackedDepths.z, linearCentralDepth);
total += weight * UnpackedAOs.z;
totalWeight += weight;
weight = BilateralWeight(UnpackedDepths.w, linearCentralDepth);
total += weight * UnpackedAOs.w;
totalWeight += weight;
// Third set of gathered data.
UV = ClampAndScaleUVForBilinear((centralPos + float2(0.0, 2.0)) * _AOBufferSize.zw, _AOBufferSize.zw);
GatherAOData(_AOPackedData, UV, UnpackedAOs, UnpackedDepths);
weight = BilateralWeight(UnpackedDepths.x, linearCentralDepth);
total += weight * UnpackedAOs.x;
totalWeight += weight;
weight = BilateralWeight(UnpackedDepths.y, linearCentralDepth);
total += weight * UnpackedAOs.y;
totalWeight += weight;
weight = BilateralWeight(UnpackedDepths.z, linearCentralDepth);
total += weight * UnpackedAOs.z;
totalWeight += weight;
weight = BilateralWeight(UnpackedDepths.w, linearCentralDepth);
total += weight * UnpackedAOs.w;
totalWeight += weight;
// Fourth set of gathered data.
UV = ClampAndScaleUVForBilinear((centralPos + float2(2.0, 2.0)) * _AOBufferSize.zw, _AOBufferSize.zw);
GatherAOData(_AOPackedData, UV, UnpackedAOs, UnpackedDepths);
weight = BilateralWeight(UnpackedDepths.x, linearCentralDepth);
total += weight * UnpackedAOs.x;
totalWeight += weight;
weight = BilateralWeight(UnpackedDepths.y, linearCentralDepth);
total += weight * UnpackedAOs.y;
totalWeight += weight;
weight = BilateralWeight(UnpackedDepths.z, linearCentralDepth);
total += weight * UnpackedAOs.z;
totalWeight += weight;
weight = BilateralWeight(UnpackedDepths.w, linearCentralDepth);
total += weight * UnpackedAOs.w;
totalWeight += weight;
total /= totalWeight;
#if DEBUG_VISUALIZE_BILATERAL_WEIGHTS
return totalWeight / 16.0f;
#endif
return total;
}
[numthreads(8, 8, 1)]
void SpatialDenoise(uint3 dispatchThreadId : SV_DispatchThreadID)
{
UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z);
float centralDepth, centralAO;
float final = Blur(dispatchThreadId.xy, centralDepth, centralAO);
#if TO_TEMPORAL
_AOPackedBlurred[COORD_TEXTURE2D_X(dispatchThreadId.xy)] = PackAOOutput(final, centralDepth);
#else
_OcclusionTexture[COORD_TEXTURE2D_X(dispatchThreadId.xy)] = OutputFinalAO(final);
#endif
}