Skip to content

Commit 74b1fdc

Browse files
pema99Evergreen
authored andcommitted
Fix APV not working with subtractive and shadowmask mode
Jira: https://jira.unity3d.com/browse/UUM-44229 This is a continuation of https://github.cds.internal.unity3d.com/unity/unity/pull/43294 Adaptive Probe Volumes (APV) do currently work correctly with mixed lighting modes (Subtractive, Distance shadowmask, Shadowmask) - APV does not store per-probe occlusion like the old light probe system did. This results in missing shadows when use the aforementioned mode. This has resulted in a long standing bug (due to scale of the fix) which has been reported several times by our users. Mixed Lighting is enabled by default and used particularly heavily on mobile. This PR changes APV to store the missing occlusion data, allowing for proper shadowing when using mixed lighting. The changes include: - Adding the new occlusion data to APV. It has its own data-file and texture. It is stored in 4 bytes representing [0;1] values for 4 lights per probe. - Implementing streaming, scenario blending and dilation for the new occlusion data. - Adding a mode to the debug visualization tool which allows viewing the occlusion data. - Adding an API function that allows getting shadowmask indices of baked lights. This was missing and required to calculate the occlusion data. - Updating shader code of the SRP's to allow sampling occlusion. - I've added a new define, `USE_APV_PROBE_OCCLUSION`, which is defined when probe occlusion should be sampled from APV. This is _not_ a new keyword, it's simply an alias for some existing keywords. This define is used to strip all the added code related to occlusion sampling when it isn't needed (in particular, when we aren't using mixed lighting). - For HDRP, I just sample the occlusion in the GBuffer pass. There's already a slot in the GBuffer for it, it was just not being set before. - For URP, the scale of changes is greater. APV supports being sampled both in vertex and fragment shader. For fragment shader sampling, the changes are simple enough, I've changed the code of relevant shaders to read occlusion and feed it to the existing designated outputs. For vertex shader sampling, I had to add a new (conditionally-defined) variable to each relevant `Varyings` struct. To a user, the change is seamless: If they were using mixed lighting before, their project was missing shadows. If they re-bake after this change, the missing shadows will appear. Before: ![Unity_EAyMvR5nGB](https://media.github.cds.internal.unity3d.com/user/2392/files/8923ec63-4677-4058-8360-ff4e0ddc6573) After: ![Unity_FTa9q6bm6h](https://media.github.cds.internal.unity3d.com/user/2392/files/0216cbe5-da2a-4ed5-b195-2d8b86142dc5) Debug view mode (mimics shadowmask view mode): ![Unity_DW4PdGQfNb](https://media.github.cds.internal.unity3d.com/user/2392/files/56179498-cc3f-4f0a-9bae-af2d245283c7)
1 parent 30d6d86 commit 74b1fdc

File tree

96 files changed

+6629
-133
lines changed

Some content is hidden

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

96 files changed

+6629
-133
lines changed

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ struct DilatedProbe
4444
public Vector4 SO_L0L1;
4545
public Vector3 SO_Direction;
4646

47+
public Vector4 ProbeOcclusion;
48+
4749
void ToSphericalHarmonicsL2(ref SphericalHarmonicsL2 sh)
4850
{
4951
SphericalHarmonicsL2Utils.SetCoefficient(ref sh, 0, L0);
@@ -90,6 +92,9 @@ internal void FromSphericalHarmonicsShaderConstants(ProbeReferenceVolume.Cell ce
9092
var directions = ProbeVolumeConstantRuntimeResources.GetSkySamplingDirections();
9193
SO_Direction = id == 255 ? Vector3.zero : directions[id];
9294
}
95+
96+
if (cellChunkData.probeOcclusion.Length != 0)
97+
ReadFromShaderCoeffsProbeOcclusion(ref ProbeOcclusion, cellChunkData.probeOcclusion, index);
9398
}
9499

95100
internal void ToSphericalHarmonicsShaderConstants(ProbeReferenceVolume.Cell cell, int probeIdx)
@@ -108,6 +113,9 @@ internal void ToSphericalHarmonicsShaderConstants(ProbeReferenceVolume.Cell cell
108113
WriteToShaderSkyOcclusion(SO_L0L1, cellChunkData.skyOcclusionDataL0L1, index * 4);
109114
if (cellChunkData.skyShadingDirectionIndices.Length != 0)
110115
cellChunkData.skyShadingDirectionIndices[index] = (byte)SkyOcclusionBaker.EncodeSkyShadingDirection(SO_Direction);
116+
117+
if (cellChunkData.probeOcclusion.Length != 0)
118+
WriteToShaderProbeOcclusion(ProbeOcclusion, cellChunkData.probeOcclusion, index * 4);
111119
}
112120
}
113121

@@ -328,6 +336,8 @@ static void PerformDilation(ProbeReferenceVolume.Cell cell, ProbeVolumeBakingSet
328336
cmd.SetGlobalTexture(ProbeReferenceVolume.ShaderIDs._APVResL2_2, rr.L2_2);
329337
cmd.SetGlobalTexture(ProbeReferenceVolume.ShaderIDs._APVResL2_3, rr.L2_3);
330338

339+
cmd.SetGlobalTexture(ProbeReferenceVolume.ShaderIDs._APVProbeOcclusion, rr.ProbeOcclusion ?? (RenderTargetIdentifier)CoreUtils.whiteVolumeTexture);
340+
331341
cmd.SetComputeTextureParam(dilationShader, dilationKernel, ProbeReferenceVolume.ShaderIDs._SkyOcclusionTexL0L1, rr.SkyOcclusionL0L1 ?? (RenderTargetIdentifier)CoreUtils.blackVolumeTexture);
332342
cmd.SetComputeTextureParam(dilationShader, dilationKernel, ProbeReferenceVolume.ShaderIDs._SkyShadingDirectionIndicesTex, rr.SkyShadingDirectionIndices ?? (RenderTargetIdentifier)CoreUtils.blackVolumeTexture);
333343
cmd.SetComputeBufferParam(dilationShader, dilationKernel, ProbeReferenceVolume.ShaderIDs._SkyPrecomputedDirections, rr.SkyPrecomputedDirections);

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ struct DilatedProbe
1919
float3 L2_4;
2020
float4 SO_L0L1;
2121
float3 SO_Direction;
22+
float4 ProbeOcclusion;
2223
};
2324

2425

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

Lines changed: 116 additions & 16 deletions
Large diffs are not rendered by default.

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

Lines changed: 99 additions & 6 deletions
Large diffs are not rendered by default.

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

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ struct BakingCell
2626
public Vector4[] skyOcclusionDataL0L1;
2727
public byte[] skyShadingDirectionIndices;
2828
public float[] validity;
29+
public Vector4[] probeOcclusion;
2930
public byte[] layerValidity;
3031
public Vector3[] offsetVectors;
3132
public float[] touchupVolumeInteraction;
@@ -220,7 +221,7 @@ void ReadAdjustmentVolumes(ProbeVolumeBakingSet bakingSet, BakingBatch bakingBat
220221
}
221222

222223
internal void SetBakedData(ProbeVolumeBakingSet bakingSet, BakingBatch bakingBatch, TouchupVolumeWithBoundsList localTouchupVolumes, int i, int probeIndex,
223-
in SphericalHarmonicsL2 sh, float validity, NativeArray<uint> renderingLayerMasks, NativeArray<Vector3> virtualOffsets, NativeArray<Vector4> skyOcclusion, NativeArray<uint> skyDirection)
224+
in SphericalHarmonicsL2 sh, float validity, NativeArray<uint> renderingLayerMasks, NativeArray<Vector3> virtualOffsets, NativeArray<Vector4> skyOcclusion, NativeArray<uint> skyDirection, NativeArray<Vector4> probeOcclusion)
224225
{
225226
byte layerValidityMask = (byte)(renderingLayerMasks.IsCreated ? renderingLayerMasks[probeIndex] : 0);
226227

@@ -246,6 +247,9 @@ internal void SetBakedData(ProbeVolumeBakingSet bakingSet, BakingBatch bakingBat
246247
this.validity[i] = currValidity;
247248
for (int l = 0; l < APVDefinitions.probeMaxRegionCount; l++)
248249
validityNeighbourMask[l, i] = currValidityNeighbourMask;
250+
251+
if (probeOcclusion.IsCreated)
252+
this.probeOcclusion[i] = probeOcclusion[probeIndex];
249253
}
250254

251255
internal int GetBakingHashCode()
@@ -473,7 +477,7 @@ public void Init(ProbeVolumeBakingSet bakingSet, NativeList<Vector3> probePositi
473477
defaultSOJob.jobs = jobs;
474478

475479
lightingJob = lightingOverride ?? new DefaultLightTransport();
476-
lightingJob.Initialize(sortedPositions);
480+
lightingJob.Initialize(ProbeVolumeLightingTab.GetLightingSettings().mixedBakeMode != MixedLightingMode.IndirectOnly, sortedPositions);
477481
if (lightingJob is DefaultLightTransport defaultLightingJob)
478482
defaultLightingJob.jobs = jobs;
479483

@@ -1059,7 +1063,8 @@ static void BakeDelegate(ref float progress, ref bool done)
10591063
s_BakeData.lightingJob.irradiance, s_BakeData.lightingJob.validity,
10601064
s_BakeData.layerMaskJob.renderingLayerMasks,
10611065
s_BakeData.virtualOffsetJob.offsets,
1062-
s_BakeData.skyOcclusionJob.occlusion, s_BakeData.skyOcclusionJob.encodedDirections);
1066+
s_BakeData.skyOcclusionJob.occlusion, s_BakeData.skyOcclusionJob.encodedDirections,
1067+
s_BakeData.lightingJob.occlusion);
10631068

10641069
if (s_BakeData.cellIndex >= m_BakingBatch.cells.Count)
10651070
s_BakeData.step++;

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ public override void PrepareForBuild(BuildPlayerContext buildPlayerContext)
112112
PrepareStreamableAsset(scenario.Value.cellDataAsset, basePath, useStreamingAsset);
113113
if (maxSHBands == ProbeVolumeSHBands.SphericalHarmonicsL2)
114114
PrepareStreamableAsset(scenario.Value.cellOptionalDataAsset, basePath, useStreamingAsset);
115+
PrepareStreamableAsset(scenario.Value.cellProbeOcclusionDataAsset, basePath, useStreamingAsset);
115116
}
116117

117118
processedBakingSets.Add(bakingSet);

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

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ RWStructuredBuffer<DilatedProbe> _OutputProbes;
2727

2828

2929
// Sampling is copied from SampleAPV()
30-
void AddProbeSample(APVResources apvRes, float3 uvw, inout DilatedProbe probe, float weight, inout float shWeight, inout float soWeight)
30+
void AddProbeSample(APVResources apvRes, float3 uvw, inout DilatedProbe probe, float weight, inout float shWeight, inout float soWeight, inout float poWeight)
3131
{
3232
// SH data
3333
float4 L0_L1Rx = SAMPLE_TEXTURE3D_LOD(apvRes.L0_L1Rx, s_point_clamp_sampler, uvw, 0).rgba;
@@ -55,6 +55,13 @@ void AddProbeSample(APVResources apvRes, float3 uvw, inout DilatedProbe probe, f
5555
shWeight += weight;
5656
}
5757

58+
float4 probeOcclusion = SAMPLE_TEXTURE3D_LOD(apvRes.ProbeOcclusion, s_linear_clamp_sampler, uvw, 0).rgba;
59+
if (!all(probeOcclusion < 0.0001f))
60+
{
61+
probe.ProbeOcclusion = probeOcclusion * weight;
62+
poWeight += weight;
63+
}
64+
5865
// Sky occlusion data
5966
if (_APVSkyOcclusionWeight > 0)
6067
{
@@ -104,7 +111,7 @@ void DilateCell(uint3 id : SV_DispatchThreadID)
104111

105112
float3 uvw;
106113
uint subdiv;
107-
float shWeight = 0, soWeight = 0;
114+
float shWeight = 0, soWeight = 0, poWeight = 0;
108115
float3 uvwDelta = rcp(_APVPoolDim);
109116

110117
float3 biasedPosWS;
@@ -137,7 +144,7 @@ void DilateCell(uint3 id : SV_DispatchThreadID)
137144
{
138145
d *= d;
139146
}
140-
AddProbeSample(FillAPVResources(), sampleUVW, probe, rcp(d), shWeight, soWeight);
147+
AddProbeSample(FillAPVResources(), sampleUVW, probe, rcp(d), shWeight, soWeight, poWeight);
141148
}
142149
}
143150
}
@@ -153,6 +160,12 @@ void DilateCell(uint3 id : SV_DispatchThreadID)
153160
probe.SO_L0L1 *= rcp(soWeight);
154161
probe.SO_Direction = SafeNormalize(probe.SO_Direction);
155162

163+
if (poWeight > 0)
164+
{
165+
probe.ProbeOcclusion *= rcp(poWeight);
166+
probe.ProbeOcclusion = saturate(probe.ProbeOcclusion);
167+
}
168+
156169
_OutputProbes[probeIdx] = probe;
157170
}
158171
}

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

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -301,7 +301,12 @@ float3 CalculateDiffuseLighting(v2f i)
301301
float3 normal = normalize(i.normal);
302302

303303
float3 skyShadingDirection = normal;
304-
if (_ShadingMode == DEBUGPROBESHADINGMODE_SKY_DIRECTION)
304+
if (_ShadingMode == DEBUGPROBESHADINGMODE_PROBE_OCCLUSION)
305+
{
306+
float4 shadowmask = apvRes.ProbeOcclusion[texLoc];
307+
return float4(shadowmask.rgb * 0.5 + (shadowmask.a * 0.5), 1);
308+
}
309+
else if (_ShadingMode == DEBUGPROBESHADINGMODE_SKY_DIRECTION)
305310
{
306311
if (_APVSkyDirectionWeight > 0)
307312
{

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@
7373
UNITY_SETUP_INSTANCE_ID(i);
7474

7575
if (_ShadingMode >= DEBUGPROBESHADINGMODE_SH && _ShadingMode <= DEBUGPROBESHADINGMODE_SHL0L1
76-
|| _ShadingMode == DEBUGPROBESHADINGMODE_SKY_OCCLUSION_SH || _ShadingMode == DEBUGPROBESHADINGMODE_SKY_DIRECTION)
76+
|| _ShadingMode == DEBUGPROBESHADINGMODE_SKY_OCCLUSION_SH || _ShadingMode == DEBUGPROBESHADINGMODE_SKY_DIRECTION || _ShadingMode == DEBUGPROBESHADINGMODE_PROBE_OCCLUSION)
7777
{
7878
return float4(CalculateDiffuseLighting(i) * exp2(_ExposureCompensation) * GetCurrentExposureMultiplier(), 1);
7979
}

0 commit comments

Comments
 (0)