Skip to content

Commit fb54e64

Browse files
adrien-de-tocquevilleEvergreen
authored andcommitted
[APV] Fix leak reduction mode in complex cases
Updated the leak reduction mode to Performance/Quality options ![image](https://media.github.cds.internal.unity3d.com/user/2154/files/e643a61d-a90a-48a4-980e-0fb6140d285c) Performance is the same as previous ValidityBased mode. Does a single sample with warped UVW Quality is a new one that does up to 3 samples and never samples an invalid probe to eliminate leaking. See improvement on the difficult case of the tent in the URP sample scene | Performance | Quality | | -- | -- | | ![image](https://media.github.cds.internal.unity3d.com/user/2154/files/12b7105f-00f3-4f31-b82d-f4d928725fae) | ![image](https://media.github.cds.internal.unity3d.com/user/2154/files/2fa02f0a-2e2b-455a-83b9-b919b7188f3a) |
1 parent 13a1172 commit fb54e64

24 files changed

+639
-446
lines changed

Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Dilate.cs

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ internal void FromSphericalHarmonicsShaderConstants(ProbeReferenceVolume.Cell ce
8787
if (cellChunkData.skyShadingDirectionIndices.Length != 0)
8888
{
8989
int id = cellChunkData.skyShadingDirectionIndices[index];
90-
var directions = DynamicSkyPrecomputedDirections.GetPrecomputedDirections();
90+
var directions = ProbeVolumeConstantRuntimeResources.GetSkySamplingDirections();
9191
SO_Direction = id == 255 ? Vector3.zero : directions[id];
9292
}
9393
}
@@ -171,7 +171,6 @@ public void Dispose()
171171
static readonly int _ProbePositionsBuffer = Shader.PropertyToID("_ProbePositionsBuffer");
172172
static readonly int _NeedDilating = Shader.PropertyToID("_NeedDilating");
173173
static readonly int _DilationParameters = Shader.PropertyToID("_DilationParameters");
174-
static readonly int _DilationParameters2 = Shader.PropertyToID("_DilationParameters2");
175174
static readonly int _OutputProbes = Shader.PropertyToID("_OutputProbes");
176175

177176
// Can definitively be optimized later on.
@@ -296,8 +295,7 @@ static void PerformDilation(ProbeReferenceVolume.Cell cell, ProbeVolumeBakingSet
296295
// There's an upper limit on the number of bricks supported inside a single cell
297296
int probeCount = Mathf.Min(cell.data.probePositions.Length, ushort.MaxValue * ProbeBrickPool.kBrickProbeCountTotal);
298297

299-
cmd.SetComputeVectorParam(dilationShader, _DilationParameters, new Vector4(probeCount, settings.dilationValidityThreshold, settings.dilationDistance, ProbeReferenceVolume.instance.MinBrickSize()));
300-
cmd.SetComputeVectorParam(dilationShader, _DilationParameters2, new Vector4(settings.squaredDistWeighting ? 1 : 0, bakingSet.skyOcclusion ? 1 : 0, bakingSet.skyOcclusionShadingDirection ? 1 : 0, 0));
298+
cmd.SetComputeVectorParam(dilationShader, _DilationParameters, new Vector4(probeCount, settings.dilationValidityThreshold, settings.dilationDistance, settings.squaredDistWeighting ? 1 : 0));
301299

302300
var refVolume = ProbeReferenceVolume.instance;
303301
ProbeReferenceVolume.RuntimeResources rr = refVolume.GetRuntimeResources();
@@ -330,12 +328,11 @@ static void PerformDilation(ProbeReferenceVolume.Cell cell, ProbeVolumeBakingSet
330328
parameters.samplingNoise = 0;
331329
parameters.weight = 1f;
332330
parameters.leakReductionMode = APVLeakReductionMode.None;
333-
parameters.minValidNormalWeight = 0.0f;
334331
parameters.frameIndexForNoise = 0;
335332
parameters.reflNormalizationLowerClamp = 0.1f;
336333
parameters.reflNormalizationUpperClamp = 1.0f;
337-
parameters.skyOcclusionIntensity = 0.0f;
338-
parameters.skyOcclusionShadingDirection = false;
334+
parameters.skyOcclusionIntensity = bakingSet.skyOcclusion ? 1 : 0;
335+
parameters.skyOcclusionShadingDirection = bakingSet.skyOcclusionShadingDirection ? true : false;
339336
parameters.regionCount = 1;
340337
parameters.regionLayerMasks = 1;
341338
ProbeReferenceVolume.instance.UpdateConstantBuffer(cmd, parameters);

Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.Serialization.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,8 +326,8 @@ static void AnalyzeBrickForIndirectionEntries(ref BakingCell cell)
326326
cell.indirectionEntryInfo[i].positionInBricks = cellPosInBricks + new Vector3Int(x, y, z) * indirectionEntrySizeInBricks;
327327
cell.indirectionEntryInfo[i].hasOnlyBiggerBricks = minSubdiv > entrySubdivLevel && touchedBrick;
328328

329-
ProbeBrickIndex.IndirectionEntryUpdateInfo unused = new ProbeBrickIndex.IndirectionEntryUpdateInfo();
330-
int brickCount = ProbeReferenceVolume.instance.GetNumberOfBricksAtSubdiv(cell.indirectionEntryInfo[i], ref unused);
329+
prv.ComputeEntryMinMax(ref cell.indirectionEntryInfo[i], cell.bricks);
330+
int brickCount = ProbeReferenceVolume.GetNumberOfBricksAtSubdiv(cell.indirectionEntryInfo[i]);
331331

332332
totalIndexChunks += Mathf.CeilToInt((float)brickCount / ProbeBrickIndex.kIndexChunkSize);
333333

Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeGIBaking.SkyOcclusion.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ internal static NativeArray<uint> EncodeShadingDirection(NativeArray<Vector3> di
5555
var cs = GraphicsSettings.GetRenderPipelineSettings<ProbeVolumeBakingResources>().skyOcclusionCS;
5656
int kernel = cs.FindKernel("EncodeShadingDirection");
5757

58-
DynamicSkyPrecomputedDirections.Initialize();
58+
ProbeVolumeConstantRuntimeResources.Initialize();
5959
var precomputedShadingDirections = ProbeReferenceVolume.instance.GetRuntimeResources().SkyPrecomputedDirections;
6060

6161
int probeCount = directions.Length;
@@ -93,7 +93,7 @@ internal static NativeArray<uint> EncodeShadingDirection(NativeArray<Vector3> di
9393

9494
internal static uint EncodeSkyShadingDirection(Vector3 direction)
9595
{
96-
var precomputedDirections = DynamicSkyPrecomputedDirections.GetPrecomputedDirections();
96+
var precomputedDirections = ProbeVolumeConstantRuntimeResources.GetSkySamplingDirections();
9797

9898
uint indexMax = 255;
9999
float bestDot = -10.0f;

Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeBakingSetEditor.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,7 @@ static class Styles
8888
// Probe Invalidity section
8989
public static readonly GUIContent resetDilation = new GUIContent("Reset Dilation Settings");
9090
public static readonly GUIContent resetVirtualOffset = new GUIContent("Reset Virtual Offset Settings");
91-
public static readonly GUIContent renderingLayerMasks = new GUIContent("Rendering Layer Masks", "When enabled, geometry in a Rendering Layer will only receive lighting from probes which see Rendering Layers in the same Rendering Layer Mask. This can be used to prevent leaking across boundaries.\nGeometry not belonging to a Rendering Layer Mask will continue to sample all probes.");
91+
public static readonly GUIContent renderingLayerMasks = new GUIContent("Rendering Layer Masks", "When enabled, geometry in a Rendering Layer will only receive lighting from probes which see Rendering Layers in the same Rendering Layer Mask. This can be used to prevent leaking across boundaries.\nGeometry not belonging to a Rendering Layer Mask will continue to sample all probes. Requires Leak Reduction Mode to be enabled.");
9292
public static readonly string maskTooltip = "The Rendering Layers for this mask.";
9393
}
9494

Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumeCellDilation.compute

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,7 @@ CBUFFER_END
1818
#define _ProbeCount (uint)_DilationParameters.x
1919
#define _ValidityThreshold _DilationParameters.y
2020
#define _SearchRadius _DilationParameters.z
21-
#define _MinBrickSizeForDilation _DilationParameters.w
22-
23-
#define _SquaredDistanceWeight (_DilationParameters2.x > 0)
24-
#define _EnableSkyOcclusion (_DilationParameters2.y > 0)
25-
#define _EnableSkyDirection (_DilationParameters2.z > 0)
21+
#define _SquaredDistanceWeight (_DilationParameters.w > 0)
2622

2723
StructuredBuffer<int> _NeedDilating;
2824
StructuredBuffer<float3> _ProbePositionsBuffer;
@@ -60,17 +56,17 @@ void AddProbeSample(APVResources apvRes, float3 uvw, inout DilatedProbe probe, f
6056
}
6157

6258
// Sky occlusion data
63-
if (_EnableSkyOcclusion)
59+
if (_APVSkyOcclusionWeight > 0)
6460
{
6561
float4 SO_L0L1 = SAMPLE_TEXTURE3D_LOD(apvRes.SkyOcclusionL0L1, s_linear_clamp_sampler, uvw, 0).rgba * weight;
6662

6763
if (SO_L0L1.x >= 0.0001f)
6864
{
6965
probe.SO_L0L1 += SO_L0L1 * weight;
7066

71-
if (_EnableSkyDirection)
67+
if (_APVSkyDirectionWeight > 0)
7268
{
73-
int3 texCoord = uvw * _PoolDim - 0.5f; // No interpolation for sky shading indices
69+
int3 texCoord = uvw * _APVPoolDim - 0.5f; // No interpolation for sky shading indices
7470
uint index = LOAD_TEXTURE3D(apvRes.SkyShadingDirectionIndices, texCoord).x * 255.0;
7571

7672
probe.SO_Direction = index == 255 ? float3(0, 0, 0) : apvRes.SkyPrecomputedDirections[index].rgb * weight;
@@ -103,18 +99,18 @@ void DilateCell(uint3 id : SV_DispatchThreadID)
10399

104100
if (_NeedDilating[probeIdx] > 0)
105101
{
106-
float3 centralPosition = _ProbePositionsBuffer[probeIdx] - _WorldOffset;
102+
float3 centralPosition = _ProbePositionsBuffer[probeIdx] - _APVWorldOffset;
107103
DilatedProbe probe = (DilatedProbe)0;
108104

109105
float3 uvw;
110106
uint subdiv;
111107
float shWeight = 0, soWeight = 0;
112-
float3 uvwDelta = rcp(_PoolDim);
108+
float3 uvwDelta = rcp(_APVPoolDim);
113109

114110
float3 biasedPosWS;
115111
if (TryToGetPoolUVWAndSubdiv(FillAPVResources(), centralPosition, 0, 0, uvw, subdiv, biasedPosWS))
116112
{
117-
float stepSize = _MinBrickSizeForDilation / 3.0f;
113+
float stepSize = _APVMinBrickSize / 3.0f;
118114

119115
// Inflate search radius a bit.
120116
float radius = 1.5f * _SearchRadius;

Packages/com.unity.render-pipelines.core/Editor/Lighting/ProbeVolume/ProbeVolumesOptionsEditor.cs

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ sealed class ProbeVolumesOptionsEditor : VolumeComponentEditor
1010
SerializedDataParameter m_ScaleBiasMinProbeDistance;
1111
SerializedDataParameter m_SamplingNoise;
1212
SerializedDataParameter m_LeakReductionMode;
13-
SerializedDataParameter m_MinValidDotProdValue;
1413
SerializedDataParameter m_AnimateNoise;
1514
SerializedDataParameter m_OcclusionOnlyNormalization;
1615

@@ -26,7 +25,6 @@ public override void OnEnable()
2625
m_ScaleBiasMinProbeDistance = Unpack(o.Find(x => x.scaleBiasWithMinProbeDistance));
2726
m_SamplingNoise = Unpack(o.Find(x => x.samplingNoise));
2827
m_LeakReductionMode = Unpack(o.Find(x => x.leakReductionMode));
29-
m_MinValidDotProdValue = Unpack(o.Find(x => x.minValidDotProductValue));
3028
m_AnimateNoise = Unpack(o.Find(x => x.animateSamplingNoise));
3129
m_OcclusionOnlyNormalization = Unpack(o.Find(x => x.occlusionOnlyReflectionNormalization));
3230

@@ -44,15 +42,6 @@ public override void OnInspectorGUI()
4442
PropertyField(m_SamplingNoise);
4543
PropertyField(m_AnimateNoise);
4644
PropertyField(m_LeakReductionMode);
47-
if (m_LeakReductionMode.value.intValue == (int)APVLeakReductionMode.ValidityBased)
48-
{
49-
}
50-
else if (m_LeakReductionMode.value.intValue == (int)APVLeakReductionMode.ValidityAndNormalBased)
51-
{
52-
using (new IndentLevelScope())
53-
PropertyField(m_MinValidDotProdValue);
54-
}
55-
5645
PropertyField(m_OcclusionOnlyNormalization);
5746

5847
PropertyField(m_IntensityMultiplier);

Packages/com.unity.render-pipelines.core/Runtime/Debug/ProbeVolumeDebugBase.hlsl

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ void DoCull(inout v2f o)
103103
// snappedProbePosition_WS : worldspace position of main probe (a corner of the 8 probes cube)
104104
// samplingPosition_WS : worldspace sampling position after applying 'NormalBias' and 'ViewBias' and 'ValidityAndNormalBased Leak Reduction'
105105
// normalizedOffset : normalized offset between sampling position and snappedProbePosition
106-
void FindSamplingData(float3 posWS, float3 normalWS, uint renderingLayer, out float3 snappedProbePosition_WS, out float3 samplingPosition_WS, out float3 samplingPositionNoAntiLeak_WS, out float probeDistance, out float3 normalizedOffset, out float validityWeights[8])
106+
void FindSamplingData(float3 posWS, float3 normalWS, uint renderingLayer, out float3 snappedProbePosition_WS, out float3 samplingPositionNoAntiLeak_WS, out float probeDistance, out float3 normalizedOffset, out float validityWeights[8])
107107
{
108108
float3 cameraPosition_WS = _WorldSpaceCameraPos;
109109
float3 viewDir_WS = normalize(cameraPosition_WS - posWS);
@@ -115,33 +115,43 @@ void FindSamplingData(float3 posWS, float3 normalWS, uint renderingLayer, out fl
115115
posWS = AddNoiseToSamplingPosition(posWS, posSS, viewDir_WS);
116116
}
117117

118-
posWS -= _WorldOffset;
118+
posWS -= _APVWorldOffset;
119119

120+
// uvw
120121
APVResources apvRes = FillAPVResources();
121122
float3 uvw;
122123
uint subdiv;
123124
float3 biasedPosWS;
124125
bool valid = TryToGetPoolUVWAndSubdiv(apvRes, posWS, normalWS, viewDir_WS, uvw, subdiv, biasedPosWS);
125126

126-
probeDistance = ProbeDistance(subdiv);
127-
snappedProbePosition_WS = GetSnappedProbePosition(biasedPosWS, subdiv);
128-
129-
WarpUVWLeakReduction(apvRes, posWS, normalWS, renderingLayer, subdiv, biasedPosWS, uvw, normalizedOffset, validityWeights);
130-
131-
biasedPosWS += _WorldOffset;
132-
snappedProbePosition_WS += _WorldOffset;
133-
samplingPositionNoAntiLeak_WS = biasedPosWS;
134-
135-
if (_LeakReductionMode != 0)
127+
// Validity mask
128+
float3 texCoord = uvw * _APVPoolDim - .5f;
129+
float3 texFrac = frac(texCoord);
130+
uint validityMask = LoadValidityMask(apvRes, renderingLayer, texCoord);
131+
for (uint i = 0; i < 8; i++)
136132
{
137-
samplingPosition_WS = snappedProbePosition_WS + (normalizedOffset*probeDistance);
133+
int3 probeCoord = GetSampleOffset(i);
134+
float validityWeight = ((probeCoord.x == 1) ? texFrac.x : 1.0f - texFrac.x) *
135+
((probeCoord.y == 1) ? texFrac.y : 1.0f - texFrac.y) *
136+
((probeCoord.z == 1) ? texFrac.z : 1.0f - texFrac.z);
137+
validityWeights[i] = validityWeight * GetValidityWeight(i, validityMask);
138138
}
139-
else
139+
140+
// Sample position
141+
normalizedOffset = texFrac;
142+
if (_APVLeakReductionMode == APVLEAKREDUCTIONMODE_PERFORMANCE)
140143
{
141-
normalizedOffset = (biasedPosWS - snappedProbePosition_WS) / probeDistance;
142-
samplingPosition_WS = biasedPosWS;
144+
float3 warped = uvw;
145+
WarpUVWLeakReduction(apvRes, renderingLayer, warped);
146+
normalizedOffset += (warped - uvw) * _APVPoolDim;
143147
}
144148

149+
// stuff
150+
biasedPosWS += _APVWorldOffset;
151+
samplingPositionNoAntiLeak_WS = biasedPosWS;
152+
153+
probeDistance = ProbeDistance(subdiv);
154+
snappedProbePosition_WS = GetSnappedProbePosition(biasedPosWS, subdiv);
145155
}
146156

147157
// Return probe sampling weight
@@ -293,7 +303,7 @@ float3 CalculateDiffuseLighting(v2f i)
293303
float3 skyShadingDirection = normal;
294304
if (_ShadingMode == DEBUGPROBESHADINGMODE_SKY_DIRECTION)
295305
{
296-
if (_EnableSkyOcclusionShadingDirection > 0)
306+
if (_APVSkyDirectionWeight > 0)
297307
{
298308
float value = 1.0f / GetCurrentExposureMultiplier();
299309

@@ -314,8 +324,8 @@ float3 CalculateDiffuseLighting(v2f i)
314324
}
315325
else
316326
{
317-
float skyOcclusion = 0.0f;
318-
if (_SkyOcclusionIntensity > 0)
327+
float3 skyOcclusion = _DebugEmptyProbeData.xyz;
328+
if (_APVSkyOcclusionWeight > 0)
319329
{
320330
// L0 L1
321331
float4 temp = float4(kSHBasis0, kSHBasis1 * normal.x, kSHBasis1 * normal.y, kSHBasis1 * normal.z);
@@ -324,10 +334,7 @@ float3 CalculateDiffuseLighting(v2f i)
324334

325335
if (_ShadingMode == DEBUGPROBESHADINGMODE_SKY_OCCLUSION_SH)
326336
{
327-
if(_SkyOcclusionIntensity > 0)
328-
return skyOcclusion / GetCurrentExposureMultiplier();
329-
else
330-
return _DebugEmptyProbeData.xyz / GetCurrentExposureMultiplier();
337+
return skyOcclusion / GetCurrentExposureMultiplier();
331338
}
332339
else
333340
{
@@ -355,7 +362,7 @@ float3 CalculateDiffuseLighting(v2f i)
355362

356363
bakeDiffuseLighting += EvalL2(L0, L2_R, L2_G, L2_B, L2_C, normal);
357364
#endif
358-
if (_SkyOcclusionIntensity > 0)
365+
if (_APVSkyOcclusionWeight > 0)
359366
bakeDiffuseLighting += skyOcclusion * EvaluateAmbientProbe(skyShadingDirection);
360367

361368
return bakeDiffuseLighting;

0 commit comments

Comments
 (0)