143 lines
4.7 KiB
Plaintext
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
|
|
}
|