Skip to content

Commit c0c514a

Browse files
adrien-de-tocquevilleEvergreen
authored andcommitted
[HDRP] Fix issue with cloud upscaling
* Fixed perceptual blending when enabling atmospheric scattering. * Fixed upscaling and reprojection around object borders * Fixed upscaling when there is a checkerboard pattern in the depth buffer * Optimized memory usage when project is using R11G11B10 and anti-ghosting is on * Enabled anti-ghosting by default * Optimized depth downsampling + reprojection + upscaling Checkerboard example: The green object is doing checkerboard fading via shadergraph and is behind behind the clouds, previously you would see it through the clouds | before | after | | -- | -- | | ![image](https://media.github.cds.internal.unity3d.com/user/2154/files/abb9001b-5002-421d-a53f-6aee66af9fce) | ![image](https://media.github.cds.internal.unity3d.com/user/2154/files/5218a853-f6bc-4c90-8cc0-8d1994b7c5e5) |
1 parent eecd5e6 commit c0c514a

File tree

41 files changed

+1137
-1315
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

41 files changed

+1137
-1315
lines changed

Packages/com.unity.render-pipelines.core/Runtime/Utilities/CoreUtils.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1148,6 +1148,22 @@ public static void SetKeyword(CommandBuffer cmd, string keyword, bool state)
11481148
cmd.DisableShaderKeyword(keyword);
11491149
}
11501150

1151+
/// <summary>
1152+
/// Set a local keyword on a ComputeShader using a CommandBuffer
1153+
/// </summary>
1154+
/// <param name="cmd">CommandBuffer on which to set the global keyword.</param>
1155+
/// <param name="cs">Compute Shader on which to set the keyword.</param>
1156+
/// <param name="keyword">Keyword to be set.</param>
1157+
/// <param name="state">Value of the keyword to be set.</param>
1158+
public static void SetKeyword(CommandBuffer cmd, ComputeShader cs, string keyword, bool state)
1159+
{
1160+
var kw = new LocalKeyword(cs, keyword);
1161+
if (state)
1162+
cmd.EnableKeyword(cs, kw);
1163+
else
1164+
cmd.DisableKeyword(cs, kw);
1165+
}
1166+
11511167
/// <summary>
11521168
/// Set a global keyword using a RasterCommandBuffer
11531169
/// </summary>
@@ -1162,7 +1178,7 @@ public static void SetKeyword(BaseCommandBuffer cmd, string keyword, bool state)
11621178
cmd.m_WrappedCommandBuffer.DisableShaderKeyword(keyword);
11631179
}
11641180

1165-
// Caution: such a call should not be use interlaced with command buffer command, as it is immediate
1181+
// Caution: such a call should not be use interleaved with command buffer command, as it is immediate
11661182
/// <summary>
11671183
/// Set a keyword immediately on a Material.
11681184
/// </summary>
@@ -1177,7 +1193,7 @@ public static void SetKeyword(Material material, string keyword, bool state)
11771193
material.DisableKeyword(keyword);
11781194
}
11791195

1180-
// Caution: such a call should not be use interlaced with command buffer command, as it is immediate
1196+
// Caution: such a call should not be use interleaved with command buffer command, as it is immediate
11811197
/// <summary>
11821198
/// Set a keyword immediately on a Material.
11831199
/// </summary>
@@ -1192,8 +1208,9 @@ public static void SetKeyword(Material material, LocalKeyword keyword, bool stat
11921208
material.DisableKeyword(keyword);
11931209
}
11941210

1211+
// Caution: such a call should not be use interleaved with command buffer command, as it is immediate
11951212
/// <summary>
1196-
/// Set a keyword to a compute shader
1213+
/// Set a keyword immediately on a compute shader
11971214
/// </summary>
11981215
/// <param name="cs">Compute Shader on which to set the keyword.</param>
11991216
/// <param name="keyword">Keyword to be set.</param>

Packages/com.unity.render-pipelines.high-definition/Editor/Lighting/VolumetricClouds/VolumetricCloudsEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ public override void OnEnable()
177177
static public readonly GUIContent k_CloudMapTilingText = EditorGUIUtility.TrTextContent("Cloud Map Tiling", "Tiling (x,y) of the cloud map.");
178178
static public readonly GUIContent k_CloudMapOffsetText = EditorGUIUtility.TrTextContent("Cloud Map Offset", "Offset (x,y) of the cloud map.");
179179
static public readonly GUIContent k_GlobalHorizontalWindSpeedText = EditorGUIUtility.TrTextContent("Global Horizontal Wind Speed", "Sets the global horizontal wind speed in kilometers per hour.\nThis value can be relative to the Global Wind Speed defined in the Visual Environment.");
180-
static public readonly GUIContent k_PerceptualBlending = EditorGUIUtility.TrTextContent("Perceptual Blending", "When enabled, the clouds will blend in a perceptual way with the environment. This may cause artifacts when the sky is over-exposed.");
180+
static public readonly GUIContent k_PerceptualBlending = EditorGUIUtility.TrTextContent("Perceptual Blending", "When enabled, the clouds will blend in a perceptual way with the environment. This may cause artifacts when the sky is over-exposed.\nThis only works when MSAA is off.");
181181

182182
void MicroDetailsSection()
183183
{

Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,6 +231,21 @@ public enum VolumetricCloudsDebug
231231
Depth,
232232
}
233233

234+
/// <summary>
235+
/// List of Depth Pyramid Full Screen Debug views.
236+
/// </summary>
237+
public enum DepthPyramidDebugView
238+
{
239+
/// <summary>
240+
/// Closest depth.
241+
/// </summary>
242+
ClosestDepth,
243+
/// <summary>
244+
/// Checkerboard of minimum and maximum depth.
245+
/// </summary>
246+
CheckerboardDepth,
247+
}
248+
234249
/// <summary>
235250
/// Class managing debug display in HDRP.
236251
/// </summary>
@@ -280,6 +295,8 @@ public partial class DebugData
280295
public Vector4 fullScreenDebugDepthRemap = new Vector4(0.0f, 1.0f, 0.0f, 0.0f);
281296
/// <summary>Current full screen debug mode mip level (when applicable).</summary>
282297
public float fullscreenDebugMip = 0.0f;
298+
/// <summary>Enable to show checkerboard depths instead of closest depths (when applicable).</summary>
299+
public DepthPyramidDebugView depthPyramidView = DepthPyramidDebugView.ClosestDepth;
283300
/// <summary>Index of the light used for contact shadows display.</summary>
284301
public int fullScreenContactShadowLightIndex = 0;
285302
/// <summary>XR single pass test mode.</summary>
@@ -378,6 +395,7 @@ public partial class DebugData
378395
internal int lightClusterCategoryDebug;
379396
internal int historyBufferFrameIndex = 0;
380397
internal int stpDebugModeEnumIndex;
398+
internal int depthPyramidViewEnumIndex;
381399

382400
private float m_DebugGlobalMipBiasOverride = 0.0f;
383401

@@ -1246,6 +1264,7 @@ static class LightingStrings
12461264
public static readonly NameAndTooltip FullscreenDebugMode = new() { name = "Fullscreen Debug Mode", tooltip = "Use the drop-down to select a rendering mode to display as an overlay on the screen." };
12471265
public static readonly NameAndTooltip ScreenSpaceShadowIndex = new() { name = "Screen Space Shadow Index", tooltip = "Select the index of the screen space shadows to view with the slider. There must be a Light in the scene that uses Screen Space Shadows." };
12481266
public static readonly NameAndTooltip DepthPyramidDebugMip = new() { name = "Debug Mip", tooltip = "Enable to view a lower-resolution mipmap." };
1267+
public static readonly NameAndTooltip DepthPyramidDebugView = new() { name = "Debug View", tooltip = "Use the down-down to select which depth pyramid data to show in this view." };
12491268
public static readonly NameAndTooltip DepthPyramidEnableRemap = new() { name = "Enable Depth Remap", tooltip = "Enable remapping of displayed depth values for better vizualization." };
12501269
public static readonly NameAndTooltip DepthPyramidRangeMin = new() { name = "Depth Range Min Value", tooltip = "Distance at which depth values remap starts (0 is near plane, 1 is far plane)" };
12511270
public static readonly NameAndTooltip DepthPyramidRangeMax = new() { name = "Depth Range Max Value", tooltip = "Distance at which depth values remap ends (0 is near plane, 1 is far plane)" };
@@ -1593,6 +1612,16 @@ void RegisterLightingDebug()
15931612
children =
15941613
{
15951614
new DebugUI.FloatField { nameAndTooltip = LightingStrings.DepthPyramidDebugMip, getter = () => data.fullscreenDebugMip, setter = value => data.fullscreenDebugMip = value, min = () => 0f, max = () => 1f, incStep = 0.05f },
1615+
new DebugUI.EnumField()
1616+
{
1617+
isHiddenCallback = () => data.fullScreenDebugMode != FullScreenDebugMode.DepthPyramid,
1618+
nameAndTooltip = LightingStrings.DepthPyramidDebugView,
1619+
getter = () => (int)data.depthPyramidView,
1620+
setter = value => { data.depthPyramidView = (DepthPyramidDebugView)value; },
1621+
autoEnum = typeof(DepthPyramidDebugView),
1622+
getIndex = () => data.depthPyramidViewEnumIndex,
1623+
setIndex = value => { data.depthPyramidViewEnumIndex = value; },
1624+
},
15961625
new DebugUI.BoolField { nameAndTooltip = LightingStrings.DepthPyramidEnableRemap, getter = () => data.enableDebugDepthRemap, setter = value => data.enableDebugDepthRemap = value },
15971626
new DebugUI.Container()
15981627
{

Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugDisplay.hlsl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,6 @@
1616
// Local shader variables
1717
static SHADOW_TYPE g_DebugShadowAttenuation = 0;
1818

19-
StructuredBuffer<int2> _DebugDepthPyramidOffsets;
20-
2119
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/PBRValidator.hlsl"
2220

2321
// When displaying lux meter we compress the light in order to be able to display value higher than 65504

Packages/com.unity.render-pipelines.high-definition/Runtime/Debug/DebugFullScreen.shader

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ Shader "Hidden/HDRP/DebugFullScreen"
3535
float _QuadOverdrawMaxQuadCost;
3636
float _VertexDensityMaxPixelCost;
3737
uint _DebugContactShadowLightIndex;
38-
int _DebugDepthPyramidMip;
38+
float4 _DebugDepthPyramidParams; // (mip index, offset_x, offset_y, unused)
3939
float _MinMotionVector;
4040
float4 _MotionVecIntensityParams;
4141
float _FogVolumeOverdrawMaxValue;
@@ -440,11 +440,13 @@ Shader "Hidden/HDRP/DebugFullScreen"
440440
}
441441
if (_FullScreenDebugMode == FULLSCREENDEBUGMODE_DEPTH_PYRAMID)
442442
{
443+
int debugDepthPyramidMip = _DebugDepthPyramidParams.x;
444+
int2 debugDepthPyramidOffset = int2(_DebugDepthPyramidParams.yz);
445+
443446
// Reuse depth display function from DebugViewMaterial
444-
int2 mipOffset = _DebugDepthPyramidOffsets[_DebugDepthPyramidMip];
445-
uint2 remappedPos = (uint2)(input.texcoord.xy * _DebugViewportSize.xy);
446-
uint2 pixCoord = (uint2)remappedPos.xy >> _DebugDepthPyramidMip;
447-
float depth = LOAD_TEXTURE2D_X(_CameraDepthTexture, pixCoord + mipOffset).r;
447+
uint2 samplePosition = (uint2)((input.texcoord.xy / _RTHandleScale.xy) * _DebugViewportSize.xy);
448+
uint2 pixCoord = (uint2)samplePosition >> debugDepthPyramidMip;
449+
float depth = LOAD_TEXTURE2D_X(_CameraDepthTexture, pixCoord + debugDepthPyramidOffset).r;
448450
PositionInputs posInput = GetPositionInput(input.positionCS.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V);
449451

450452
// We square the factors to have more precision near zero which is where people usually want to visualize depth.

Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/ScreenSpaceLighting/BilateralUpsample.hlsl

Lines changed: 18 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -86,17 +86,17 @@ float BilUpSingle_Uniform(float HiDepth, float4 LowDepths, float4 lowValue)
8686
// them in this structure
8787
struct NeighborhoodUpsampleData3x3
8888
{
89-
// Low resolution depths
89+
// Low resolution scene depths
9090
float4 lowDepthA;
9191
float4 lowDepthB;
9292
float lowDepthC;
9393

94-
// The low resolution masks
95-
float4 lowMasksA;
96-
float4 lowMasksB;
97-
float lowMasksC;
94+
// The low resolution depth values
95+
float4 lowDepthValueA;
96+
float4 lowDepthValueB;
97+
float lowDepthValueC;
9898

99-
// The low resolution values
99+
// The low resolution color values
100100
float4 lowValue0;
101101
float4 lowValue1;
102102
float4 lowValue2;
@@ -113,60 +113,10 @@ struct NeighborhoodUpsampleData3x3
113113
float lowWeightC;
114114
};
115115

116-
void EvaluateMaskValidity(float linearHighDepth, float lowDepth, int currentIndex,
117-
inout float inputMask, inout int closestNeighhor,
118-
inout float currentDistance)
119-
{
120-
if (inputMask == 0.0f)
121-
return;
122-
123-
// Convert the depths to linear
124-
float candidateLinearDepth = Linear01Depth(lowDepth, _ZBufferParams);
125-
126-
// Compute the distance between the two values
127-
float candidateDistance = abs(linearHighDepth - candidateLinearDepth);
128-
129-
// Evaluate if this becomes the closest neighbor
130-
if (candidateDistance < currentDistance)
131-
{
132-
closestNeighhor = currentIndex;
133-
currentDistance = candidateDistance;
134-
}
135-
136-
bool validSample = candidateDistance < (linearHighDepth * 0.3);
137-
inputMask = validSample ? 1.0f : 0.0f;
138-
}
139-
140-
void OverrideMaskValues(float highDepth, inout NeighborhoodUpsampleData3x3 data,
141-
out bool rejectedNeighborhood, out int closestNeighbor)
142-
{
143-
// First of all compute the linear version of the high depth
144-
float linearHighDepth = Linear01Depth(highDepth, _ZBufferParams);
145-
float currentDistance = 1.0f;
146-
147-
closestNeighbor = 4; // Index of the closest neighbor (center by default)
148-
149-
// The center has precedence over the other pixels
150-
EvaluateMaskValidity(linearHighDepth, data.lowDepthB.x, 4, data.lowMasksB.x, closestNeighbor, currentDistance);
151-
152-
// Then the plus
153-
EvaluateMaskValidity(linearHighDepth, data.lowDepthA.y, 1, data.lowMasksA.y, closestNeighbor, currentDistance);
154-
EvaluateMaskValidity(linearHighDepth, data.lowDepthA.w, 3, data.lowMasksA.w, closestNeighbor, currentDistance);
155-
EvaluateMaskValidity(linearHighDepth, data.lowDepthB.y, 5, data.lowMasksB.y, closestNeighbor, currentDistance);
156-
EvaluateMaskValidity(linearHighDepth, data.lowDepthB.w, 7, data.lowMasksB.w, closestNeighbor, currentDistance);
157-
158-
// Then the cross
159-
EvaluateMaskValidity(linearHighDepth, data.lowDepthA.x, 0, data.lowMasksA.x, closestNeighbor, currentDistance);
160-
EvaluateMaskValidity(linearHighDepth, data.lowDepthA.z, 2, data.lowMasksA.z, closestNeighbor, currentDistance);
161-
EvaluateMaskValidity(linearHighDepth, data.lowDepthB.z, 6, data.lowMasksB.z, closestNeighbor, currentDistance);
162-
EvaluateMaskValidity(linearHighDepth, data.lowDepthC, 8, data.lowMasksC, closestNeighbor, currentDistance);
163-
164-
// Flag that tells us which pixel holds valid information
165-
rejectedNeighborhood = (currentDistance >= (linearHighDepth * 0.3));
166-
}
167-
168116
// The bilateral upscale function (3x3 neighborhood)
169-
float4 BilUpColor3x3(float highDepth, in NeighborhoodUpsampleData3x3 data)
117+
// Perform joint bilateral upsampling using the scene depth as guide signal
118+
// https://bartwronski.com/2019/09/22/local-linear-models-guided-filter/
119+
void BilUpColor3x3(float highDepth, in NeighborhoodUpsampleData3x3 data, out float4 outColor, out float outDepth)
170120
{
171121
float4 combinedWeightsA = data.lowWeightA / (abs(highDepth - data.lowDepthA) + _UpsampleTolerance);
172122
float4 combinedWeightsB = data.lowWeightB / (abs(highDepth - data.lowDepthB) + _UpsampleTolerance);
@@ -186,8 +136,15 @@ float4 BilUpColor3x3(float highDepth, in NeighborhoodUpsampleData3x3 data)
186136
+ data.lowValue6 * combinedWeightsB.z
187137
+ data.lowValue7 * combinedWeightsB.w
188138
+ data.lowValue8 * combinedWeightsC
189-
+ float4(_NoiseFilterStrength, _NoiseFilterStrength, _NoiseFilterStrength, 0.0);
190-
return WeightedSum / TotalWeight;
139+
+ float4(_NoiseFilterStrength.xxx, 0.0f);
140+
141+
float WeightedDepth = dot(data.lowDepthValueA, combinedWeightsA)
142+
+ dot(data.lowDepthValueB, combinedWeightsB)
143+
+ data.lowDepthValueC * combinedWeightsC
144+
+ _NoiseFilterStrength;
145+
146+
outColor = WeightedSum / TotalWeight;
147+
outDepth = WeightedDepth / TotalWeight;
191148
}
192149

193150
// Due to compiler issues, it is not possible to use arrays to store the neighborhood values, we then store them in this structure

0 commit comments

Comments
 (0)