Skip to content

Commit fb2e68c

Browse files
svc-reach-platform-supportEvergreen
authored andcommitted
[Port] [6000.4] [UUM-97985] Fix HDRP FPTL and Cluster artifacts when having many lights
1 parent c92d27e commit fb2e68c

File tree

3 files changed

+68
-5
lines changed

3 files changed

+68
-5
lines changed

Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoop.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -860,7 +860,7 @@ void LightLoopNewFrame(CommandBuffer cmd, HDCamera hdCamera)
860860

861861
static int NumLightIndicesPerClusteredTile()
862862
{
863-
return ShaderConfig.FPTLMaxLightCount * (1 << k_Log2NumClusters); // total footprint for all layers of the tile (measured in light index entries)
863+
return (ShaderConfig.FPTLMaxLightCount + 1) * (1 << (k_Log2NumClusters + 1)); // total footprint for all layers of the tile (measured in light index entries)
864864
}
865865

866866
void LightLoopAllocResolutionDependentBuffers(HDCamera hdCamera, int width, int height)

Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/lightlistbuild-clustered.compute

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,9 @@ RWStructuredBuffer<float> g_logBaseBuffer : register( u3 ); // don't
6161

6262

6363
#define MAX_NR_COARSE_ENTRIES LIGHT_CLUSTER_MAX_COARSE_ENTRIES
64+
#define MAX_NR_VISIBLE_LIGHTS 826 // correspond to m_MaxLightsOnScreen in LightLoop.cs
6465

66+
groupshared unsigned int ldsTilePassList[MAX_NR_VISIBLE_LIGHTS];
6567
groupshared unsigned int coarseList[MAX_NR_COARSE_ENTRIES];
6668
groupshared unsigned int clusterIdxs[MAX_NR_COARSE_ENTRIES/2];
6769
groupshared float4 lightPlanes[4*6]; // Each plane is defined by a float4. 6 planes per light, 4 lights (24 planes)
@@ -241,6 +243,16 @@ void LIGHTLISTGEN(uint threadID : SV_GroupIndex, uint3 u3GroupID : SV_GroupID)
241243

242244
uint2 tileIDX = u3GroupID.xy;
243245
uint t=threadID;
246+
int i;
247+
248+
const bool lightSortRequired = g_iNrVisibLights > MAX_NR_COARSE_ENTRIES; // Uniform runtime branch
249+
if (lightSortRequired)
250+
{
251+
UNITY_LOOP
252+
for(i=t; i<MAX_NR_VISIBLE_LIGHTS; i+=NR_THREADS)
253+
if(i<MAX_NR_VISIBLE_LIGHTS)
254+
ldsTilePassList[i]=0;
255+
}
244256

245257
const uint log2TileSize = firstbithigh(TILE_SIZE_CLUSTERED);
246258
uint nrTilesX = ((uint)g_screenSize.x +(TILE_SIZE_CLUSTERED-1))>>log2TileSize;
@@ -340,7 +352,27 @@ void LIGHTLISTGEN(uint threadID : SV_GroupIndex, uint3 u3GroupID : SV_GroupID)
340352
unsigned int uInc = 1;
341353
unsigned int uIndex;
342354
InterlockedAdd(lightOffs, uInc, uIndex);
343-
if(uIndex<MAX_NR_COARSE_ENTRIES) coarseList[uIndex] = l; // add to light list
355+
if (lightSortRequired)
356+
ldsTilePassList[l] = 1;
357+
else
358+
if(uIndex<MAX_NR_COARSE_ENTRIES) coarseList[uIndex] = l; // add to light list
359+
}
360+
}
361+
362+
if (lightSortRequired)
363+
{
364+
#if NR_THREADS > PLATFORM_LANE_COUNT
365+
GroupMemoryBarrierWithGroupSync();
366+
#endif
367+
// Ascending sort to prevent unpredictable light list when the number of visible lights is greater than the coarse entries.
368+
if(t==0)
369+
{
370+
int c=0;
371+
for(int ii=0; ii<g_iNrVisibLights && c < MAX_NR_COARSE_ENTRIES; ii++)
372+
{
373+
if(ldsTilePassList[ii] == 1)
374+
coarseList[c++] = ii;
375+
}
344376
}
345377
}
346378

@@ -399,7 +431,7 @@ void LIGHTLISTGEN(uint threadID : SV_GroupIndex, uint3 u3GroupID : SV_GroupID)
399431
//////////////////////////////////////////////////////////
400432

401433
uint start = 0;
402-
int i=(int) t;
434+
i=(int) t;
403435
int iSpaceAvail = 0;
404436
int iSum = 0;
405437
if(i<nrClusters)

Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/lightlistbuild.compute

Lines changed: 33 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ StructuredBuffer<uint> g_vBigTileLightList : register( t4 ); // don't sup
4949
RWStructuredBuffer<uint> g_vLightList : register( u0 ); // don't support RWBuffer yet in unity
5050

5151
#define CATEGORY_LIST_SIZE LIGHTCATEGORY_COUNT
52+
#define MAX_NR_VISIBLE_LIGHTS 826 // correspond to m_MaxLightsOnScreen in LightLoop.cs
5253

54+
groupshared unsigned int ldsTilePassList[MAX_NR_VISIBLE_LIGHTS];
5355
groupshared unsigned int coarseList[LIGHT_LIST_MAX_COARSE_ENTRIES];
5456
groupshared unsigned int prunedList[LIGHT_LIST_MAX_COARSE_ENTRIES]; // temporarily support room for all 64 while in LDS
5557

@@ -155,6 +157,15 @@ void TileLightListGen(uint3 dispatchThreadId : SV_DispatchThreadID, uint threadI
155157
if(i<LIGHT_LIST_MAX_COARSE_ENTRIES)
156158
prunedList[i]=0;
157159

160+
const bool lightSortRequired = g_iNrVisibLights > LIGHT_LIST_MAX_COARSE_ENTRIES; // Uniform runtime branch
161+
if (lightSortRequired)
162+
{
163+
UNITY_LOOP
164+
for(i=t; i<MAX_NR_VISIBLE_LIGHTS; i+=NR_THREADS)
165+
if(i<MAX_NR_VISIBLE_LIGHTS)
166+
ldsTilePassList[i]=0;
167+
}
168+
158169
uint iWidth = g_viDimensions.x;
159170
uint iHeight = g_viDimensions.y;
160171
uint nrTilesX = (iWidth+15)/16;
@@ -244,14 +255,34 @@ void TileLightListGen(uint3 dispatchThreadId : SV_DispatchThreadID, uint threadI
244255
unsigned int uInc = 1;
245256
unsigned int uIndex;
246257
InterlockedAdd(lightOffs, uInc, uIndex);
247-
if(uIndex<LIGHT_LIST_MAX_COARSE_ENTRIES) coarseList[uIndex] = l; // add to light list
258+
if (lightSortRequired)
259+
ldsTilePassList[l] = 1;
260+
else
261+
if(uIndex<LIGHT_LIST_MAX_COARSE_ENTRIES) coarseList[uIndex] = l; // add to light list
248262
}
249263
}
250264

251265
#ifdef FINE_PRUNING_ENABLED
252266
if(t<LIGHT_FPTL_VISIBILITY_DWORD_COUNTS) ldsDoesLightIntersect[t] = 0;
253267
#endif
254268

269+
if (lightSortRequired)
270+
{
271+
#if NR_THREADS > PLATFORM_LANE_COUNT
272+
GroupMemoryBarrierWithGroupSync();
273+
#endif
274+
// Ascending sort to prevent unpredictable light list when the number of visible lights is greater than the coarse entries.
275+
if(t==0)
276+
{
277+
int c=0;
278+
for(int ii=0; ii<g_iNrVisibLights && c < LIGHT_LIST_MAX_COARSE_ENTRIES; ii++)
279+
{
280+
if(ldsTilePassList[ii] == 1)
281+
coarseList[c++] = ii;
282+
}
283+
}
284+
}
285+
255286
#if NR_THREADS > PLATFORM_LANE_COUNT
256287
GroupMemoryBarrierWithGroupSync();
257288
#endif
@@ -626,7 +657,7 @@ void FinePruneLights(uint threadID, int iNrCoarseLights, uint2 viTilLL, float vL
626657
if (uIndex < LIGHT_LIST_MAX_COARSE_ENTRIES)
627658
{
628659
// InterlockedAdd ensures atomic and ordered writing to prunedList, preventing threads from overwriting each other's values.
629-
// Increment ldsNrLightsFinal (represents the total number of lights for the tile).
660+
// Increment ldsNrLightsFinal (represents the total number of lights for the tile).
630661
unsigned int uInc = 1;
631662
unsigned int finalPrunedLightIndex;
632663
InterlockedAdd(ldsNrLightsFinal, uInc, finalPrunedLightIndex);

0 commit comments

Comments
 (0)