Skip to content

Commit 2db0232

Browse files
authored
Process both Visible and Dynamic GI lights at the same time (#82)
* Process both Visible and Dynamic GI lights at the same time * Removed (unused) directional DGI lights * Removed (unused) LightVolumeType array
1 parent a40de51 commit 2db0232

File tree

7 files changed

+330
-343
lines changed

7 files changed

+330
-343
lines changed

com.unity.render-pipelines.high-definition/Runtime/Lighting/Light/HDGpuLightsBuilder.Jobs.cs

Lines changed: 46 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,14 @@ internal struct CreateGpuLightDataJob : IJobParallelFor
5353
[ReadOnly]
5454
public int outputDirectionalLightCounts;
5555
[ReadOnly]
56+
public int outputDGILightCounts;
57+
[ReadOnly]
5658
public int outputLightBoundsCount;
5759
[ReadOnly]
5860
public CreateGpuLightDataJobGlobalConfig globalConfig;
5961
[ReadOnly]
6062
public Vector3 cameraPos;
6163
[ReadOnly]
62-
public int directionalSortedLightCounts;
63-
[ReadOnly]
6464
public bool isPbrSkyActive;
6565
[ReadOnly]
6666
public int precomputedAtmosphericAttenuation;
@@ -70,12 +70,6 @@ internal struct CreateGpuLightDataJob : IJobParallelFor
7070
public int viewCounts;
7171
[ReadOnly]
7272
public bool useCameraRelativePosition;
73-
[ReadOnly]
74-
public bool skipDirectionalLights;
75-
[ReadOnly]
76-
public bool modulateByBounceIntensity;
77-
[ReadOnly]
78-
public bool computeLightDataVolumeAndBound;
7973

8074
//sky settings
8175
[ReadOnly]
@@ -101,6 +95,8 @@ internal struct CreateGpuLightDataJob : IJobParallelFor
10195
[ReadOnly]
10296
public NativeArray<uint> sortKeys;
10397
[ReadOnly]
98+
public NativeArray<uint> dgiSortKeys;
99+
[ReadOnly]
104100
public NativeArray<HDProcessedVisibleLight> processedEntities;
105101
[ReadOnly]
106102
public NativeArray<VisibleLight> visibleLights;
@@ -123,6 +119,9 @@ internal struct CreateGpuLightDataJob : IJobParallelFor
123119
public NativeArray<DirectionalLightData> directionalLights;
124120
[WriteOnly]
125121
[NativeDisableContainerSafetyRestriction]
122+
public NativeArray<LightData> dgiLights;
123+
[WriteOnly]
124+
[NativeDisableContainerSafetyRestriction]
126125
public NativeArray<LightsPerView> lightsPerView;
127126
[WriteOnly]
128127
[NativeDisableContainerSafetyRestriction]
@@ -133,6 +132,9 @@ internal struct CreateGpuLightDataJob : IJobParallelFor
133132
[WriteOnly]
134133
[NativeDisableContainerSafetyRestriction]
135134
public NativeArray<int> gpuLightCounters;
135+
[WriteOnly]
136+
[NativeDisableContainerSafetyRestriction]
137+
public NativeArray<int> dgiGpuLightCounters;
136138
#endregion
137139

138140
private ref HDLightRenderData GetLightData(int dataIndex)
@@ -157,11 +159,11 @@ private static uint GetLightLayer(bool lightLayersEnabled, in HDLightRenderData
157159

158160
private static Vector3 GetLightColor(in VisibleLight light) => new Vector3(light.finalColor.r, light.finalColor.g, light.finalColor.b);
159161

160-
private void IncrementCounter(HDGpuLightsBuilder.GPULightTypeCountSlots counterSlot)
162+
private void IncrementCounter(ref NativeArray<int> counterSet, HDGpuLightsBuilder.GPULightTypeCountSlots counterSlot)
161163
{
162164
unsafe
163165
{
164-
int* ptr = (int*)gpuLightCounters.GetUnsafePtr<int>() + (int)counterSlot;
166+
int* ptr = (int*)counterSet.GetUnsafePtr<int>() + (int)counterSlot;
165167
Interlocked.Increment(ref UnsafeUtility.AsRef<int>(ptr));
166168
}
167169
}
@@ -364,7 +366,8 @@ public static void ConvertLightToGPUFormat(
364366

365367
private void StoreAndConvertLightToGPUFormat(
366368
int outputIndex, int lightIndex,
367-
LightCategory lightCategory, GPULightType gpuLightType, LightVolumeType lightVolumeType)
369+
LightCategory lightCategory, GPULightType gpuLightType, LightVolumeType lightVolumeType,
370+
bool isDGI)
368371
{
369372
bool isFromVisibleList = lightIndex < visibleLights.Length;
370373
var light = isFromVisibleList ? visibleLights[lightIndex] : visibleOffscreenLights[lightIndex - visibleLights.Length];
@@ -373,7 +376,7 @@ private void StoreAndConvertLightToGPUFormat(
373376
ref HDLightRenderData lightRenderData = ref GetLightData(processedEntity.dataIndex);
374377

375378
ConvertLightToGPUFormat(
376-
lightCategory, gpuLightType, globalConfig,
379+
lightCategory, gpuLightType, globalConfig,
377380
visibleLightShadowCasterMode[lightIndex],
378381
visibleLightBakingOutput[lightIndex],
379382
light,
@@ -382,12 +385,14 @@ private void StoreAndConvertLightToGPUFormat(
382385
out var lightDimensions,
383386
ref lightData);
384387

385-
if (modulateByBounceIntensity)
388+
// DGI lights get modulated by light bounce intensity
389+
if (isDGI)
386390
{
387391
lightData.color *= visibleLightBounceIntensity[lightIndex];
388392
}
389393

390-
if (computeLightDataVolumeAndBound)
394+
// Volume and Bound data is only calculated for visible (non-DGI) lights
395+
if (!isDGI)
391396
{
392397
for (int viewId = 0; viewId < viewCounts; ++viewId)
393398
{
@@ -401,24 +406,28 @@ private void StoreAndConvertLightToGPUFormat(
401406
if (useCameraRelativePosition)
402407
lightData.positionRWS -= cameraPos;
403408

409+
var counterSet = !isDGI ? gpuLightCounters : dgiGpuLightCounters;
410+
int maxLightCount = !isDGI ? outputLightCounts : outputDGILightCounts;
411+
var outputArray = !isDGI ? lights : dgiLights;
412+
404413
switch (lightCategory)
405414
{
406415
case LightCategory.Punctual:
407-
IncrementCounter(HDGpuLightsBuilder.GPULightTypeCountSlots.Punctual);
416+
IncrementCounter(ref counterSet, HDGpuLightsBuilder.GPULightTypeCountSlots.Punctual);
408417
break;
409418
case LightCategory.Area:
410-
IncrementCounter(HDGpuLightsBuilder.GPULightTypeCountSlots.Area);
419+
IncrementCounter(ref counterSet, HDGpuLightsBuilder.GPULightTypeCountSlots.Area);
411420
break;
412421
default:
413422
Debug.Assert(false, "TODO: encountered an unknown LightCategory.");
414423
break;
415424
}
416425

417426
#if DEBUG
418-
if (outputIndex < 0 || outputIndex >= outputLightCounts)
427+
if (outputIndex < 0 || outputIndex >= maxLightCount)
419428
throw new Exception("Trying to access an output index out of bounds. Output index is " + outputIndex + "and max length is " + outputLightCounts);
420429
#endif
421-
lights[outputIndex] = lightData;
430+
outputArray[outputIndex] = lightData;
422431
}
423432

424433
private void ComputeLightVolumeDataAndBound(
@@ -699,33 +708,40 @@ private void ConvertDirectionalLightToGPUFormat(
699708
if (useCameraRelativePosition)
700709
lightData.positionRWS -= cameraPos;
701710

702-
IncrementCounter(HDGpuLightsBuilder.GPULightTypeCountSlots.Directional);
711+
IncrementCounter(ref gpuLightCounters, HDGpuLightsBuilder.GPULightTypeCountSlots.Directional);
703712

704713
#if DEBUG
705714
if (outputIndex < 0 || outputIndex >= outputDirectionalLightCounts)
706-
throw new Exception("Trying to access an output index out of bounds. Output index is " + outputIndex + "and max length is " + outputLightCounts);
715+
throw new Exception("Trying to access an output index out of bounds. Output index is " + outputIndex + "and max length is " + outputDirectionalLightCounts);
707716
#endif
708717

709718
directionalLights[outputIndex] = lightData;
710719
}
711720

712721
public void Execute(int index)
713722
{
714-
var sortKey = sortKeys[index];
723+
int totalVisibleLights = outputLightCounts + outputDirectionalLightCounts;
724+
725+
bool isDGI = index >= totalVisibleLights;
726+
int localIndex = !isDGI ? index : (index - totalVisibleLights);
727+
728+
var sortKey = !isDGI ? sortKeys[localIndex] : dgiSortKeys[localIndex];
715729
HDGpuLightsBuilder.UnpackLightSortKey(sortKey, out var lightCategory, out var gpuLightType, out var lightVolumeType, out var lightIndex);
716730

717731
if (gpuLightType == GPULightType.Directional)
718732
{
719-
if (!skipDirectionalLights)
733+
if (!isDGI) // While we setup output buffers for directional DGI lights, they're never used, so we skip processing them
720734
{
721-
int outputIndex = index;
735+
int outputIndex = localIndex;
722736
ConvertDirectionalLightToGPUFormat(outputIndex, lightIndex, lightCategory, gpuLightType, lightVolumeType);
723737
}
724738
}
725739
else
726740
{
727-
int outputIndex = index - directionalSortedLightCounts;
728-
StoreAndConvertLightToGPUFormat(outputIndex, lightIndex, lightCategory, gpuLightType, lightVolumeType);
741+
int outputIndex = localIndex;
742+
if (!isDGI)
743+
outputIndex = localIndex - outputDirectionalLightCounts;
744+
StoreAndConvertLightToGPUFormat(outputIndex, lightIndex, lightCategory, gpuLightType, lightVolumeType, isDGI);
729745
}
730746
}
731747
}
@@ -748,16 +764,15 @@ public void StartCreateGpuLightDataJob(
748764
totalLightCounts = lightEntities.lightCount,
749765
outputLightCounts = m_LightCount,
750766
outputDirectionalLightCounts = m_DirectionalLightCount,
767+
outputDGILightCounts = m_DGILightCount,
751768
outputLightBoundsCount = m_LightBoundsCount,
752769
globalConfig = CreateGpuLightDataJobGlobalConfig.Create(hdCamera, hdShadowSettings),
753770
cameraPos = hdCamera.camera.transform.position,
754-
directionalSortedLightCounts = visibleLights.sortedDirectionalLightCounts,
755771
isPbrSkyActive = isPbrSkyActive,
756772
precomputedAtmosphericAttenuation = ShaderConfig.s_PrecomputedAtmosphericAttenuation,
757773
defaultDataIndex = lightEntities.GetEntityDataIndex(lightEntities.GetDefaultLightEntity()),
758774
viewCounts = hdCamera.viewCount,
759775
useCameraRelativePosition = ShaderConfig.s_CameraRelativeRendering != 0,
760-
skipDirectionalLights = SkipDirectionalLights,
761776

762777
planetCenterPosition = skySettings.GetPlanetCenterPosition(hdCamera.camera.transform.position),
763778
planetaryRadius = skySettings.GetPlanetaryRadius(),
@@ -771,6 +786,7 @@ public void StartCreateGpuLightDataJob(
771786

772787
//visible lights processed
773788
sortKeys = visibleLights.sortKeys,
789+
dgiSortKeys = visibleLights.sortKeysDGI,
774790
processedEntities = visibleLights.processedEntities,
775791
visibleLights = cullingResult.visibleLights,
776792
visibleOffscreenLights = cullingResult.visibleOffscreenVertexLights,
@@ -780,40 +796,22 @@ public void StartCreateGpuLightDataJob(
780796

781797
//outputs
782798
gpuLightCounters = m_LightTypeCounters,
799+
dgiGpuLightCounters = m_DGILightTypeCounters,
783800
lights = m_Lights,
784801
directionalLights = m_DirectionalLights,
802+
dgiLights = m_DGILights,
785803
lightsPerView = m_LightsPerView,
786804
lightBounds = m_LightBounds,
787805
lightVolumes = m_LightVolumes
788806
};
789-
OverrideCreateGpuLightDataJobParameters(ref createGpuLightDataJob);
790807

791-
m_CreateGpuLightDataJobHandle = createGpuLightDataJob.Schedule(visibleLights.sortedLightCounts, 32);
808+
m_CreateGpuLightDataJobHandle = createGpuLightDataJob.Schedule(visibleLights.sortedLightCounts + visibleLights.sortedDGILightCounts, 32);
792809
}
793810

794811
public void CompleteGpuLightDataJob()
795812
{
796813
m_CreateGpuLightDataJobHandle.Complete();
797814
}
798-
799-
protected abstract void OverrideCreateGpuLightDataJobParameters(ref CreateGpuLightDataJob job);
800-
}
801-
802-
internal partial class HDGpuLightsRegularBuilder : HDGpuLightsBuilder
803-
{
804-
protected override void OverrideCreateGpuLightDataJobParameters(ref CreateGpuLightDataJob job)
805-
{
806-
job.modulateByBounceIntensity = false;
807-
job.computeLightDataVolumeAndBound = true;
808-
}
809815
}
810816

811-
internal partial class HDGpuLightsDynamicBuilder : HDGpuLightsBuilder
812-
{
813-
protected override void OverrideCreateGpuLightDataJobParameters(ref CreateGpuLightDataJob job)
814-
{
815-
job.modulateByBounceIntensity = true;
816-
job.computeLightDataVolumeAndBound = false;
817-
}
818-
}
819817
}

0 commit comments

Comments
 (0)