Skip to content

Commit 7d67fb8

Browse files
DGI Fix Leak Mitigation (#68)
* Fixed DGI axis bit packing. * Store neighbor validity in axis and limit propagation from an invalid probe instead of limiting propagation towards an invalid probe. * Set default Baked Emission Multiplier, Sky Multiplier and Leak Multiplier to 1.0.
1 parent 57ea525 commit 7d67fb8

File tree

8 files changed

+55
-60
lines changed

8 files changed

+55
-60
lines changed

com.unity.render-pipelines.high-definition/Runtime/Lighting/ProbeVolume/DynamicGI/ProbeDynamicGI.cs

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,5 @@
11
using System;
2-
using UnityEngine.Rendering;
3-
using UnityEngine.Serialization;
4-
using UnityEditor.Experimental;
5-
using Unity.Collections;
6-
using System.Collections.Generic;
72
using System.Runtime.CompilerServices;
8-
using System.Runtime.InteropServices;
9-
using UnityEditor;
10-
using UnityEditor.Rendering.HighDefinition;
11-
using UnityEngine.Experimental.Rendering;
123

134
[assembly: InternalsVisibleTo("Unity.Entities.Hybrid.HybridComponents")]
145
[assembly: InternalsVisibleTo("Unity.Rendering.Hybrid")]
@@ -18,13 +9,13 @@ namespace UnityEngine.Rendering.HighDefinition
189
public class ProbeDynamicGI : VolumeComponent
1910
{
2011
[Tooltip("Indirect multiplier for all lights affect Dynamic GI")]
21-
public ClampedFloatParameter indirectMultiplier = new ClampedFloatParameter(1f, 0.0f, 2f);
12+
public ClampedFloatParameter indirectMultiplier = new ClampedFloatParameter(1f, 0f, 2f);
2213
[Tooltip("Multiplier for material emissive colors that affect Dynamic GI")]
23-
public ClampedFloatParameter bakedEmissionMultiplier = new ClampedFloatParameter(0f, 0f, 2f);
14+
public ClampedFloatParameter bakedEmissionMultiplier = new ClampedFloatParameter(1f, 0f, 2f);
2415
[Tooltip("Multiplier for sky lighting that affect Dynamic GI of")]
25-
public ClampedFloatParameter skyMultiplier = new ClampedFloatParameter(0f, 0f, 2f);
16+
public ClampedFloatParameter skyMultiplier = new ClampedFloatParameter(1f, 0f, 2f);
2617
[Tooltip("A control for blending in more influence of infinite bounce light near surfaces")]
27-
public ClampedFloatParameter infiniteBounce = new ClampedFloatParameter(1f, 0.0f, 2f);
18+
public ClampedFloatParameter infiniteBounce = new ClampedFloatParameter(1f, 0f, 2f);
2819
[Tooltip("Limits albedo value used for infinite bounces to prevent lighting from blowing up")]
2920
public ClampedFloatParameter maxAlbedo = new ClampedFloatParameter(0.9f, 0f, 1f);
3021
[Tooltip("Advanced control for the contribution amount of secondary propagation indirect light")]
@@ -43,8 +34,8 @@ public class ProbeDynamicGI : VolumeComponent
4334
public ClampedFloatParameter sharpness = new ClampedFloatParameter(6.0f, 0.0f, 16.0f);
4435
[Tooltip("Advanced control for the SG sharpness used when propagating light")]
4536
public ClampedFloatParameter propagationSharpness = new ClampedFloatParameter(2.0f, 0.0f, 16.0f);
46-
[Tooltip("Advanced control for darkening down the indirect light on invalid probes")]
47-
public ClampedFloatParameter leakMultiplier = new ClampedFloatParameter(0.0f, 0.0f, 1.0f);
37+
[Tooltip("Advanced control for darkening down the indirect light coming from invalid probes")]
38+
public ClampedFloatParameter leakMultiplier = new ClampedFloatParameter(1.0f, 0.0f, 1.0f);
4839
[Tooltip("Advanced control to bias the distance from the normal of the hit surface to perform direct lighting evaluation on")]
4940
public ClampedFloatParameter bias = new ClampedFloatParameter(0.05f, 0.0f, 0.33f);
5041
[Tooltip("Advanced control for how probes at volume boundaries propagate light from neighboring Probe Volumes.\n\nDisabled: No light is propagated across neighbors.\n\nSample Neighbors Direction Only: Samples all probe volumes once per probe and evaluates light from the resulting probe data for each axis.\n\nSample Neighbors Position and Direction: Samples all probe volumes for all propagation axes at each axes neighboring probe position.\nPotentially more accurate than Sample Neighbors Direction Only, but significantly more expensive.")]

com.unity.render-pipelines.high-definition/Runtime/Lighting/ProbeVolume/DynamicGI/ProbePropagation.hlsl

Lines changed: 2 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -26,21 +26,10 @@ float3 ReadPreviousPropagationAxis(uint probeIndex, uint axisIndex)
2626
return _PreviousRadianceCacheAxis[index];
2727
}
2828

29-
float3 NormalizeOutputRadiance(float3 lighting, float probeValidity)
29+
float InvalidScale(float probeValidity)
3030
{
3131
float validity = pow(1.0 - probeValidity, 8.0);
32-
const float invalidScale = (1.0f - lerp(_LeakMultiplier, 0.0f, validity));
33-
34-
float3 radiance = lighting * invalidScale;
35-
36-
return radiance;
37-
}
38-
39-
void WritePropagationOutput(uint index, float3 lighting, float probeValidity)
40-
{
41-
const float3 finalRadiance = NormalizeOutputRadiance(lighting, probeValidity);
42-
_RadianceCacheAxis[index] = finalRadiance;
32+
return 1.0f - lerp(_LeakMultiplier, 0.0f, validity);
4333
}
4434

45-
4635
#endif // endof PROBE_PROPAGATION

com.unity.render-pipelines.high-definition/Runtime/Lighting/ProbeVolume/DynamicGI/ProbePropagationAxes.compute

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,6 @@ void PropagateLight(uint3 id : SV_DispatchThreadID)
259259

260260
float3 incomingHitRadiance = 0;
261261
float3 incomingMissRadiance = 0;
262-
float probeValidity = 0;
263262
int neighborAxisIndexOffset = axisIndex * NEIGHBOR_AXIS_COUNT;
264263

265264
BasisAxisHit basisAxisHit = ComputeBasisAxisHit(_RayAxis[axisIndex].xyz, _Sharpness);
@@ -275,7 +274,6 @@ void PropagateLight(uint3 id : SV_DispatchThreadID)
275274
uint hitIndex = 0;
276275
float probeAxisValidity = 0;
277276
UnpackIndicesAndValidityOnly(neighbor.hitIndexValidity, hitIndex, probeAxisValidity);
278-
probeValidity += probeAxisValidity;
279277

280278
BasisAxisHit basisAxisNeighborHit = ComputeBasisAxisHit(neighborAxisLookup.neighborDirection, _Sharpness);
281279

@@ -307,7 +305,7 @@ void PropagateLight(uint3 id : SV_DispatchThreadID)
307305
float3 prevAxisRadiance = ReadPreviousPropagationAxis(neighborProbeIndex, axisIndex);
308306

309307
float weight = neighborAxisLookup.propagationWeight;
310-
incomingMissRadiance += prevAxisRadiance * weight;
308+
incomingMissRadiance += prevAxisRadiance * weight * InvalidScale(probeAxisValidity);
311309
#endif
312310
}
313311
#if defined(SAMPLE_NEIGHBORS_DIRECTION_ONLY) || defined(SAMPLE_NEIGHBORS_POSITION_AND_DIRECTION)
@@ -338,9 +336,6 @@ void PropagateLight(uint3 id : SV_DispatchThreadID)
338336
}
339337
}
340338

341-
probeValidity *= 1.0 / PROPAGATION_AXIS_AMOUNT;
342-
343-
float3 lighting = (incomingHitRadiance + incomingMissRadiance) * _PropagationContribution;
344-
WritePropagationOutput(index, lighting, probeValidity);
339+
_RadianceCacheAxis[index] = (incomingHitRadiance + incomingMissRadiance) * _PropagationContribution;
345340
}
346341
}

com.unity.render-pipelines.high-definition/Runtime/Lighting/ProbeVolume/DynamicGI/ProbePropagationHits.compute

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -205,7 +205,7 @@ void AccumulateLightingDirectional(uint3 id : SV_DispatchThreadID)
205205
const SurfaceHitData hit = ConstructSurfaceHit(neighborData, worldPosition, probeVolumeLtw);
206206

207207
#if defined(COMPUTE_INFINITE_BOUNCE)
208-
float3 lighting = EstimateIncomingBounceLightAtHit(probeIndex, hit);
208+
float3 lighting = EstimateIncomingBounceLightAtHit(probeIndex, hit) * InvalidScale(probeValidity);
209209
#else
210210
float3 lighting = 0;
211211
#endif
@@ -214,7 +214,6 @@ void AccumulateLightingDirectional(uint3 id : SV_DispatchThreadID)
214214

215215
lighting += UnpackEmission(neighborData.emission) * _BakedEmissionMultiplier;
216216

217-
const float3 finalRadiance = NormalizeOutputRadiance(lighting, probeValidity);
218-
_HitRadianceCacheAxis[hitAxisIndex] = finalRadiance;
217+
_HitRadianceCacheAxis[hitAxisIndex] = lighting;
219218
}
220219
}

com.unity.render-pipelines.high-definition/Runtime/Lighting/ProbeVolume/DynamicGI/ProbeVolumeDynamicGI.cs

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -199,10 +199,9 @@ public ProbeVolumeDynamicGIStats GetStats()
199199
return _stats;
200200
}
201201

202-
internal static void AllocateNeighbors(ref ProbeVolumePayload payload, int numMissedAxis, int numHitAxis, int numAxis)
202+
internal static void AllocateNeighbors(ref ProbeVolumePayload payload, int numHitAxis, int numAxis)
203203
{
204-
int totalAxis = numMissedAxis + numHitAxis;
205-
int totalProbes = totalAxis / s_NeighborAxis.Length;
204+
int totalProbes = numAxis / s_NeighborAxis.Length;
206205
int totalProbeNeighborCapacity = (1 << 19);
207206
Debug.Assert(totalProbes < totalProbeNeighborCapacity);
208207

@@ -211,14 +210,14 @@ internal static void AllocateNeighbors(ref ProbeVolumePayload payload, int numMi
211210
}
212211

213212

214-
internal static void EnsureNeighbors(ref ProbeVolumePayload payload, int missedNeighborAxis, int hitNeighborAxis, int neighborAxis)
213+
internal static void EnsureNeighbors(ref ProbeVolumePayload payload, int hitNeighborAxis, int neighborAxis)
215214
{
216215
if (payload.hitNeighborAxis == null
217216
|| payload.neighborAxis == null
218217
|| payload.hitNeighborAxis.Length != hitNeighborAxis
219218
|| payload.neighborAxis.Length != neighborAxis)
220219
{
221-
AllocateNeighbors(ref payload, missedNeighborAxis, hitNeighborAxis, neighborAxis);
220+
AllocateNeighbors(ref payload, hitNeighborAxis, neighborAxis);
222221
}
223222
}
224223

@@ -289,10 +288,10 @@ private static uint PackAlbedoAndDistance(Vector3 color, float distance, float m
289288

290289
uint packedOutput = 0;
291290

292-
packedOutput |= ((uint)(albedoR * 255.5f) << 0);
293-
packedOutput |= ((uint)(albedoG * 255.5f) << 8);
294-
packedOutput |= ((uint)(albedoB * 255.5f) << 16);
295-
packedOutput |= ((uint)(normalizedDistance * 255.5f) << 24);
291+
packedOutput |= (uint)(albedoR * 255f) << 0;
292+
packedOutput |= (uint)(albedoG * 255f) << 8;
293+
packedOutput |= (uint)(albedoB * 255f) << 16;
294+
packedOutput |= (uint)(normalizedDistance * 255f) << 24;
296295

297296
return packedOutput;
298297
}
@@ -324,8 +323,8 @@ private static uint PackIndexAndValidity(uint probeIndex, uint axisIndex, float
324323
uint output = 0;
325324

326325
output |= axisIndex;
327-
output |= (((uint)(validity * 255.5f) & 31) << 5);
328-
output |= (probeIndex << 13);
326+
output |= ((uint)(validity * 255f) & 255) << 5;
327+
output |= probeIndex << 13;
329328

330329
return output;
331330
}
@@ -335,8 +334,8 @@ private static uint PackIndexAndValidityOnly(uint probeIndex, float validity)
335334
{
336335
uint output = 0;
337336

338-
output |= (((uint)(validity * 255.5f) & 255) << 8);
339-
output |= (probeIndex << 8);
337+
output |= (uint)(validity * 255f) & 255;
338+
output |= probeIndex << 8;
340339

341340
return output;
342341
}

com.unity.render-pipelines.high-definition/Runtime/Lighting/ProbeVolume/DynamicGI/ProbeVolumeDynamicGI.hlsl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,11 +34,11 @@ struct NeighborAxis
3434
float4 UnpackAlbedoAndDistance(uint packedVal, float maxNeighborDistance)
3535
{
3636
float4 outVal;
37-
outVal.r = ((packedVal >> 0) & 255) / 255.5f;
38-
outVal.g = ((packedVal >> 8) & 255) / 255.5f;
39-
outVal.b = ((packedVal >> 16) & 255) / 255.5f;
37+
outVal.r = ((packedVal >> 0) & 255) / 255.0f;
38+
outVal.g = ((packedVal >> 8) & 255) / 255.0f;
39+
outVal.b = ((packedVal >> 16) & 255) / 255.0f;
4040

41-
outVal.a = ((packedVal >> 24) & 255) / 255.5f;
41+
outVal.a = ((packedVal >> 24) & 255) / 255.0f;
4242
outVal.a *= maxNeighborDistance * sqrt(3.0f);
4343

4444
return outVal;

com.unity.render-pipelines.high-definition/Runtime/Lighting/ProbeVolume/DynamicGI/ProbeVolumeDynamicGIEditor.cs

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -244,9 +244,8 @@ private void InitBakeNeighborData(ref ProbeBakeNeighborData bakeNeighborData)
244244
private void GeneratePackedNeighborData(ProbeBakeNeighborData[] neighborBakeDatas, ref ProbeVolumeAsset probeVolumeAsset, in ProbeVolumeArtistParameters parameters, int hits)
245245
{
246246
int totalAxis = neighborBakeDatas.Length * s_NeighborAxis.Length;
247-
int missedAxis = totalAxis - hits;
248-
EnsureNeighbors(ref probeVolumeAsset.payload, missedAxis, hits, totalAxis);
249-
247+
EnsureNeighbors(ref probeVolumeAsset.payload, hits, totalAxis);
248+
250249
float maxNeighborDistance = GetMaxNeighborDistance(in parameters);
251250
int missedAxisCount = 0;
252251
int hitAxisCount = 0;
@@ -261,17 +260,32 @@ private void GeneratePackedNeighborData(ProbeBakeNeighborData[] neighborBakeData
261260
var emission = neighborBakeData.neighborEmission[axis];
262261
var normal = neighborBakeData.neighborNormal[axis];
263262

263+
var neighborPos = probeVolumeAsset.ComputePos3DFrom1D(i) + ProbeVolumeAsset.s_Offsets[axis];
264+
float neighborValidity;
265+
if (neighborPos.x >= 0 && neighborPos.y >= 0 && neighborPos.z >= 0
266+
&& neighborPos.x < probeVolumeAsset.resolutionX
267+
&& neighborPos.y < probeVolumeAsset.resolutionY
268+
&& neighborPos.z < probeVolumeAsset.resolutionZ)
269+
{
270+
var neighborIndex = probeVolumeAsset.ComputeIndex1DFrom3D(neighborPos);
271+
neighborValidity = neighborBakeDatas[neighborIndex].validity;
272+
}
273+
else
274+
{
275+
neighborValidity = 0f;
276+
}
277+
264278
if (distance == 0)
265279
{
266280
// miss
267-
SetNeighborData(ref probeVolumeAsset.payload, validity, i, axis, NeighborAxis.Miss);
281+
SetNeighborData(ref probeVolumeAsset.payload, neighborValidity, i, axis, NeighborAxis.Miss);
268282
++missedAxisCount;
269283
}
270284
else
271285
{
272286
// hit
273287
SetNeighborDataHit(ref probeVolumeAsset.payload, albedo, emission, normal, distance, validity, i, axis, hitAxisCount, maxNeighborDistance );
274-
SetNeighborData(ref probeVolumeAsset.payload, validity, i, axis, (uint)hitAxisCount);
288+
SetNeighborData(ref probeVolumeAsset.payload, neighborValidity, i, axis, (uint)hitAxisCount);
275289
++hitAxisCount;
276290
}
277291
}

com.unity.render-pipelines.high-definition/Runtime/Lighting/ProbeVolume/ProbeVolumeAsset.cs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,14 @@ protected internal int ComputeIndex1DFrom3D(Vector3Int pos)
151151
return pos.x + pos.y * resolutionX + pos.z * resolutionX * resolutionY;
152152
}
153153

154+
internal Vector3Int ComputePos3DFrom1D(int index)
155+
{
156+
return new Vector3Int(
157+
index % resolutionX,
158+
index / resolutionX % resolutionY,
159+
index / (resolutionX * resolutionY));
160+
}
161+
154162
bool OverwriteInvalidProbe(ref ProbeVolumePayload payloadSrc, ref ProbeVolumePayload payloadDst, Vector3Int index3D, float backfaceTolerance)
155163
{
156164
int strideSHL01 = ProbeVolumePayload.GetDataSHL01Stride();

0 commit comments

Comments
 (0)