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.
185 lines
8.1 KiB
185 lines
8.1 KiB
#define _UpsampleTolerance 1e-5f
|
|
#define _NoiseFilterStrength 0.99999999f
|
|
|
|
|
|
// This table references the set of pixels that are used for bilateral upscale based on the expected order
|
|
static const int2 UpscaleBilateralPixels[16] = {int2(0, 0), int2(0, -1), int2(-1, -1), int2(-1, 0)
|
|
, int2(0, 0), int2(0, -1), int2(1, -1), int2(1, 0)
|
|
, int2(0, 0) , int2(-1, 0), int2(-1, 1), int2(0, 1)
|
|
, int2(0, 0), int2(1, 0), int2(1, 1), int2(0, 1), };
|
|
|
|
static const int2 IndexToLocalOffsetCoords[9] = {int2(-1, -1), int2(0, -1), int2(1, -1)
|
|
, int2(-1, 0), int2(0, 0), int2(1, 0)
|
|
, int2(-1, 1) , int2(0, 1), int2(1, 1)};
|
|
|
|
// The bilateral upscale function (2x2 neighborhood, color3 version), uniform weight version
|
|
float3 BilUpColor3_Uniform(float HiDepth, float4 LowDepths, float3 lowValue0, float3 lowValue1, float3 lowValue2, float3 lowValue3)
|
|
{
|
|
float4 weights = float4(3, 3, 3, 3) / (abs(HiDepth - LowDepths) + _UpsampleTolerance);
|
|
float TotalWeight = dot(weights, 1) + _NoiseFilterStrength;
|
|
float3 WeightedSum = lowValue0 * weights.x
|
|
+ lowValue1 * weights.y
|
|
+ lowValue2 * weights.z
|
|
+ lowValue3 * weights.w
|
|
+ _NoiseFilterStrength;
|
|
return WeightedSum / TotalWeight;
|
|
}
|
|
|
|
// THe bilateral upscale function (2x2 neighborhood, color3 version)
|
|
float3 BilUpColor3(float HiDepth, float4 LowDepths, float3 lowValue0, float3 lowValue1, float3 lowValue2, float3 lowValue3)
|
|
{
|
|
float4 weights = float4(9, 3, 1, 3) / (abs(HiDepth - LowDepths) + _UpsampleTolerance);
|
|
float TotalWeight = dot(weights, 1) + _NoiseFilterStrength;
|
|
float3 WeightedSum = lowValue0 * weights.x
|
|
+ lowValue1 * weights.y
|
|
+ lowValue2 * weights.z
|
|
+ lowValue3 * weights.w
|
|
+ _NoiseFilterStrength;
|
|
return WeightedSum / TotalWeight;
|
|
}
|
|
|
|
// THe bilateral upscale function (2x2 neighborhood, color3 version)
|
|
float3 BilUpColor3WithWeight(float HiDepth, float4 LowDepths, float3 lowValue0, float3 lowValue1, float3 lowValue2, float3 lowValue3, float4 initialWeight)
|
|
{
|
|
float4 weights = initialWeight * float4(9, 3, 1, 3) / (abs(HiDepth - LowDepths) + _UpsampleTolerance);
|
|
float TotalWeight = dot(weights, 1) + _NoiseFilterStrength;
|
|
float3 WeightedSum = lowValue0 * weights.x
|
|
+ lowValue1 * weights.y
|
|
+ lowValue2 * weights.z
|
|
+ lowValue3 * weights.w
|
|
+ _NoiseFilterStrength;
|
|
return WeightedSum / TotalWeight;
|
|
}
|
|
|
|
// The bilateral upscale function (2x2 neighborhood, color4 version)
|
|
float4 BilUpColor(float HiDepth, float4 LowDepths, float4 lowValue0, float4 lowValue1, float4 lowValue2, float4 lowValue3)
|
|
{
|
|
float4 weights = float4(9, 3, 1, 3) / (abs(HiDepth - LowDepths) + _UpsampleTolerance);
|
|
float TotalWeight = dot(weights, 1) + _NoiseFilterStrength;
|
|
float4 WeightedSum = lowValue0 * weights.x
|
|
+ lowValue1 * weights.y
|
|
+ lowValue2 * weights.z
|
|
+ lowValue3 * weights.w
|
|
+ _NoiseFilterStrength;
|
|
return WeightedSum / TotalWeight;
|
|
}
|
|
|
|
// The bilateral upscale function (2x2 neighborhood) (single channel version)
|
|
float BilUpSingle(float HiDepth, float4 LowDepths, float4 lowValue)
|
|
{
|
|
float4 weights = float4(9, 3, 1, 3) / (abs(HiDepth - LowDepths) + _UpsampleTolerance);
|
|
float TotalWeight = dot(weights, 1) + _NoiseFilterStrength;
|
|
float WeightedSum = dot(lowValue, weights) + _NoiseFilterStrength;
|
|
return WeightedSum / TotalWeight;
|
|
}
|
|
|
|
// The bilateral upscale function (2x2 neighborhood) (single channel version), uniform version
|
|
float BilUpSingle_Uniform(float HiDepth, float4 LowDepths, float4 lowValue)
|
|
{
|
|
float4 weights = float4(3, 3, 3, 3) / (abs(HiDepth - LowDepths) + _UpsampleTolerance);
|
|
float TotalWeight = dot(weights, 1) + _NoiseFilterStrength;
|
|
float WeightedSum = dot(lowValue, weights) + _NoiseFilterStrength;
|
|
return WeightedSum / TotalWeight;
|
|
}
|
|
|
|
// Due to compiler issues, it is not possible to use arrays to store the neighborhood values, we then store
|
|
// them in this structure
|
|
struct NeighborhoodUpsampleData3x3
|
|
{
|
|
// Low resolution scene depths
|
|
float4 lowDepthA;
|
|
float4 lowDepthB;
|
|
float lowDepthC;
|
|
|
|
// The low resolution depth values
|
|
float4 lowDepthValueA;
|
|
float4 lowDepthValueB;
|
|
float lowDepthValueC;
|
|
|
|
// The low resolution color values
|
|
float4 lowValue0;
|
|
float4 lowValue1;
|
|
float4 lowValue2;
|
|
float4 lowValue3;
|
|
float4 lowValue4;
|
|
float4 lowValue5;
|
|
float4 lowValue6;
|
|
float4 lowValue7;
|
|
float4 lowValue8;
|
|
|
|
// Weights used to combine the neighborhood
|
|
float4 lowWeightA;
|
|
float4 lowWeightB;
|
|
float lowWeightC;
|
|
};
|
|
|
|
// The bilateral upscale function (3x3 neighborhood)
|
|
// Perform joint bilateral upsampling using the scene depth as guide signal
|
|
// https://bartwronski.com/2019/09/22/local-linear-models-guided-filter/
|
|
void BilUpColor3x3(float highDepth, in NeighborhoodUpsampleData3x3 data, out float4 outColor, out float outDepth)
|
|
{
|
|
float4 combinedWeightsA = data.lowWeightA / (abs(highDepth - data.lowDepthA) + _UpsampleTolerance);
|
|
float4 combinedWeightsB = data.lowWeightB / (abs(highDepth - data.lowDepthB) + _UpsampleTolerance);
|
|
float combinedWeightsC = data.lowWeightC / (abs(highDepth - data.lowDepthC) + _UpsampleTolerance);
|
|
|
|
float TotalWeight = combinedWeightsA.x + combinedWeightsA.y + combinedWeightsA.z + combinedWeightsA.w
|
|
+ combinedWeightsB.x + combinedWeightsB.y + combinedWeightsB.z + combinedWeightsB.w
|
|
+ combinedWeightsC;
|
|
|
|
float4 WeightedSum = data.lowValue0 * combinedWeightsA.x
|
|
+ data.lowValue1 * combinedWeightsA.y
|
|
+ data.lowValue2 * combinedWeightsA.z
|
|
+ data.lowValue3 * combinedWeightsA.w
|
|
+ data.lowValue4 * combinedWeightsB.x
|
|
+ data.lowValue5 * combinedWeightsB.y
|
|
+ data.lowValue6 * combinedWeightsB.z
|
|
+ data.lowValue7 * combinedWeightsB.w
|
|
+ data.lowValue8 * combinedWeightsC
|
|
+ float4(_NoiseFilterStrength.xxx, 0.0f);
|
|
|
|
float WeightedDepth = dot(data.lowDepthValueA, combinedWeightsA)
|
|
+ dot(data.lowDepthValueB, combinedWeightsB)
|
|
+ data.lowDepthValueC * combinedWeightsC
|
|
+ _NoiseFilterStrength;
|
|
|
|
// This branch shouldn't be needed if we do the neighbor analysis mentionned in BuildRay
|
|
if (TotalWeight == 0.0f)
|
|
{
|
|
outColor = float4(0, 0, 0, 1);
|
|
outDepth = UNITY_NEAR_CLIP_VALUE;
|
|
}
|
|
else
|
|
{
|
|
outColor = WeightedSum / (TotalWeight + _NoiseFilterStrength);
|
|
outDepth = WeightedDepth / (TotalWeight + _NoiseFilterStrength);
|
|
}
|
|
}
|
|
|
|
// Due to compiler issues, it is not possible to use arrays to store the neighborhood values, we then store them in this structure
|
|
struct NeighborhoodUpsampleData2x2_RGB
|
|
{
|
|
// Low resolution depths
|
|
float4 lowDepth;
|
|
|
|
// The low resolution values
|
|
float3 lowValue0;
|
|
float3 lowValue1;
|
|
float3 lowValue2;
|
|
float3 lowValue3;
|
|
|
|
// Weights used to combine the neighborhood
|
|
float4 lowWeight;
|
|
};
|
|
|
|
// The bilateral upscale function (3x3 neighborhood)
|
|
float3 BilUpColor2x2_RGB(float highDepth, in NeighborhoodUpsampleData2x2_RGB data)
|
|
{
|
|
float4 combinedWeights = data.lowWeight / (abs(highDepth - data.lowDepth) + _UpsampleTolerance);
|
|
float TotalWeight = combinedWeights.x + combinedWeights.y + combinedWeights.z + combinedWeights.w + _NoiseFilterStrength;
|
|
float3 WeightedSum = data.lowValue0.xyz * combinedWeights.x
|
|
+ data.lowValue1.xyz * combinedWeights.y
|
|
+ data.lowValue2.xyz * combinedWeights.z
|
|
+ data.lowValue3.xyz * combinedWeights.w
|
|
+ _NoiseFilterStrength;
|
|
return WeightedSum / TotalWeight;
|
|
}
|