Skip to content

Commit dc5c7e4

Browse files
elliomanEvergreen
authored andcommitted
[Unity6][URP] Fixing shadow issues when using Deferred Rendering (UUM-39576, UUM-71595, UUM-71598)
This PR does the following: * Fixes UUM-39576 where additional light shadows would flicker if they exceeded the platform max for additional lights. * Fixes UUM-71595 where additional light shadows were incorrectly ordered resulting in "random" order on screen. * Fixes UUM-71598 where disabled additional lights shadows in the URP Asset had no effect when using deferred. * Small performance improvements by refactoring some things in the additional light shadow caster pass * Improved the ComputeShadowRequestHash() function by not retrieving the VisibleLight twice and having unnecessary if checks. Also made sure this code only runs in Editor and Development builds, which are the only places it's used. * Moved some checks, that were done for each light and each slice but were only needed per light * Reduced the size of various containers inside AdditoinalLightShadowCasterPass. From int to short or byte.
1 parent 8b0e6e8 commit dc5c7e4

File tree

8 files changed

+701
-346
lines changed

8 files changed

+701
-346
lines changed

Packages/com.unity.render-pipelines.universal/Runtime/DeferredLights.cs

Lines changed: 22 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,7 @@ internal void SetupLights(CommandBuffer cmd, UniversalCameraData cameraData, Vec
321321
out m_stencilVisLights,
322322
out m_stencilVisLightOffsets,
323323
ref lightData.visibleLights,
324-
lightData.additionalLightsCount != 0 || lightData.mainLightIndex >= 0,
325-
cameraData.camera.worldToCameraMatrix,
326-
cameraData.camera.orthographic,
327-
cameraData.camera.nearClipPlane
324+
lightData.additionalLightsCount != 0 || lightData.mainLightIndex >= 0
328325
);
329326

330327
{
@@ -727,10 +724,7 @@ void PrecomputeLights(
727724
out NativeArray<ushort> stencilVisLights,
728725
out NativeArray<ushort> stencilVisLightOffsets,
729726
ref NativeArray<VisibleLight> visibleLights,
730-
bool hasAdditionalLights,
731-
Matrix4x4 view,
732-
bool isOrthographic,
733-
float zNear)
727+
bool hasAdditionalLights)
734728
{
735729
const int lightTypeCount = (int)LightType.Tube + 1;
736730

@@ -807,21 +801,26 @@ void RenderStencilLights(RasterCommandBuffer cmd, UniversalLightData lightData,
807801
using (new ProfilingScope(cmd, m_ProfilingSamplerDeferredStencilPass))
808802
{
809803
NativeArray<VisibleLight> visibleLights = lightData.visibleLights;
804+
bool hasLightCookieManager = m_LightCookieManager != null;
805+
bool hasAdditionalLightPass = m_AdditionalLightsShadowCasterPass != null;
810806

811807
if (HasStencilLightsOfType(LightType.Directional))
812-
RenderStencilDirectionalLights(cmd, stripShadowsOffVariants, lightData, shadowData, visibleLights, lightData.mainLightIndex);
808+
RenderStencilDirectionalLights(cmd, stripShadowsOffVariants, lightData, shadowData, visibleLights, hasAdditionalLightPass, hasLightCookieManager, lightData.mainLightIndex);
813809

814-
if (HasStencilLightsOfType(LightType.Point))
815-
RenderStencilPointLights(cmd, stripShadowsOffVariants, lightData, shadowData, visibleLights);
810+
if (lightData.supportsAdditionalLights)
811+
{
812+
if (HasStencilLightsOfType(LightType.Point))
813+
RenderStencilPointLights(cmd, stripShadowsOffVariants, lightData, shadowData, visibleLights, hasAdditionalLightPass, hasLightCookieManager);
816814

817-
if (HasStencilLightsOfType(LightType.Spot))
818-
RenderStencilSpotLights(cmd, stripShadowsOffVariants, lightData, shadowData, visibleLights);
815+
if (HasStencilLightsOfType(LightType.Spot))
816+
RenderStencilSpotLights(cmd, stripShadowsOffVariants, lightData, shadowData, visibleLights, hasAdditionalLightPass, hasLightCookieManager);
817+
}
819818
}
820819

821820
Profiler.EndSample();
822821
}
823822

824-
void RenderStencilDirectionalLights(RasterCommandBuffer cmd, bool stripShadowsOffVariants, UniversalLightData lightData, UniversalShadowData shadowData, NativeArray<VisibleLight> visibleLights, int mainLightIndex)
823+
void RenderStencilDirectionalLights(RasterCommandBuffer cmd, bool stripShadowsOffVariants, UniversalLightData lightData, UniversalShadowData shadowData, NativeArray<VisibleLight> visibleLights, bool hasAdditionalLightPass, bool hasLightCookieManager, int mainLightIndex)
825824
{
826825
if (m_FullscreenMesh == null)
827826
m_FullscreenMesh = CreateFullscreenMesh();
@@ -830,10 +829,8 @@ void RenderStencilDirectionalLights(RasterCommandBuffer cmd, bool stripShadowsOf
830829

831830
// TODO bundle extra directional lights rendering by batches of 8.
832831
// Also separate shadow caster lights from non-shadow caster.
833-
bool isFirstLight = true;
834-
bool hasLightCookieManager = m_LightCookieManager != null;
835-
bool hasAdditionalLightPass = m_AdditionalLightsShadowCasterPass != null;
836832
int lastLightCookieIndex = -1;
833+
bool isFirstLight = true;
837834
bool lastLightCookieKeywordState = false;
838835
bool lastShadowsKeywordState = false;
839836
bool lastSoftShadowsKeywordState = false;
@@ -891,17 +888,15 @@ void RenderStencilDirectionalLights(RasterCommandBuffer cmd, bool stripShadowsOf
891888
cmd.SetKeyword(ShaderGlobalKeywords._DIRECTIONAL, false);
892889
}
893890

894-
void RenderStencilPointLights(RasterCommandBuffer cmd, bool stripShadowsOffVariants, UniversalLightData lightData, UniversalShadowData shadowData, NativeArray<VisibleLight> visibleLights)
891+
void RenderStencilPointLights(RasterCommandBuffer cmd, bool stripShadowsOffVariants, UniversalLightData lightData, UniversalShadowData shadowData, NativeArray<VisibleLight> visibleLights, bool hasAdditionalLightPass, bool hasLightCookieManager)
895892
{
896893
if (m_SphereMesh == null)
897894
m_SphereMesh = CreateSphereMesh();
898895

899896
cmd.SetKeyword(ShaderGlobalKeywords._POINT, true);
900897

901-
bool isFirstLight = true;
902-
bool hasLightCookieManager = m_LightCookieManager != null;
903-
bool hasAdditionalLightPass = m_AdditionalLightsShadowCasterPass != null;
904898
int lastLightCookieIndex = -1;
899+
bool isFirstLight = true;
905900
bool lastLightCookieKeywordState = false;
906901
bool lastShadowsKeywordState = false;
907902
bool lastSoftShadowsKeywordState = false;
@@ -933,6 +928,7 @@ void RenderStencilPointLights(RasterCommandBuffer cmd, bool stripShadowsOffVaria
933928
if (light.bakingOutput.lightmapBakeType == LightmapBakeType.Mixed)
934929
lightFlags |= (int)LightFlag.SubtractiveMixedLighting;
935930

931+
// Determine whether the light is casting shadows and what the index it should use.
936932
int shadowLightIndex = hasAdditionalLightPass ? m_AdditionalLightsShadowCasterPass.GetShadowLightIndexFromLightIndex(visLightIndex) : -1;
937933
bool hasDeferredShadows = light && light.shadows != LightShadows.None && shadowLightIndex >= 0;
938934

@@ -962,23 +958,22 @@ void RenderStencilPointLights(RasterCommandBuffer cmd, bool stripShadowsOffVaria
962958
cmd.SetKeyword(ShaderGlobalKeywords._POINT, false);
963959
}
964960

965-
void RenderStencilSpotLights(RasterCommandBuffer cmd, bool stripShadowsOffVariants, UniversalLightData lightData, UniversalShadowData shadowData, NativeArray<VisibleLight> visibleLights)
961+
void RenderStencilSpotLights(RasterCommandBuffer cmd, bool stripShadowsOffVariants, UniversalLightData lightData, UniversalShadowData shadowData, NativeArray<VisibleLight> visibleLights, bool hasAdditionalLightPass, bool hasLightCookieManager)
966962
{
967963
if (m_HemisphereMesh == null)
968964
m_HemisphereMesh = CreateHemisphereMesh();
969965

970966
cmd.SetKeyword(ShaderGlobalKeywords._SPOT, true);
971967

972-
bool isFirstLight = true;
973-
bool hasLightCookieManager = m_LightCookieManager != null;
974-
bool hasAdditionalLightPass = m_AdditionalLightsShadowCasterPass != null;
975968
int lastLightCookieIndex = -1;
969+
bool isFirstLight = true;
976970
bool lastLightCookieKeywordState = false;
977971
bool lastShadowsKeywordState = false;
978972
bool lastSoftShadowsKeywordState = false;
979973
for (int soffset = m_stencilVisLightOffsets[(int)LightType.Spot]; soffset < m_stencilVisLights.Length; ++soffset)
980974
{
981975
ushort visLightIndex = m_stencilVisLights[soffset];
976+
982977
ref VisibleLight vl = ref visibleLights.UnsafeElementAtMutable(visLightIndex);
983978
if (vl.lightType != LightType.Spot)
984979
break;
@@ -993,8 +988,7 @@ void RenderStencilSpotLights(RasterCommandBuffer cmd, bool stripShadowsOffVarian
993988
// The tighter the spot shape, the lesser inflation is needed.
994989
float guard = Mathf.Lerp(1.0f, kStencilShapeGuard, sinAlpha);
995990

996-
Vector4 lightPos, lightColor, lightAttenuation, lightSpotDir, lightOcclusionChannel;
997-
UniversalRenderPipeline.InitializeLightConstants_Common(visibleLights, visLightIndex, out lightPos, out lightColor, out lightAttenuation, out lightSpotDir, out lightOcclusionChannel);
991+
UniversalRenderPipeline.InitializeLightConstants_Common(visibleLights, visLightIndex, out Vector4 lightPos, out Vector4 lightColor, out Vector4 lightAttenuation, out Vector4 lightSpotDir, out Vector4 lightOcclusionChannel);
998992

999993
if (lightData.supportsLightLayers)
1000994
SetRenderingLayersMask(cmd, light, ShaderConstants._LightLayerMask);
@@ -1003,6 +997,7 @@ void RenderStencilSpotLights(RasterCommandBuffer cmd, bool stripShadowsOffVarian
1003997
if (light.bakingOutput.lightmapBakeType == LightmapBakeType.Mixed)
1004998
lightFlags |= (int)LightFlag.SubtractiveMixedLighting;
1005999

1000+
// Determine whether the light is casting shadows and what the index it should use.
10061001
int shadowLightIndex = hasAdditionalLightPass ? m_AdditionalLightsShadowCasterPass.GetShadowLightIndexFromLightIndex(visLightIndex) : -1;
10071002
bool hasDeferredShadows = light && light.shadows != LightShadows.None && shadowLightIndex >= 0;
10081003

@@ -1032,7 +1027,6 @@ void RenderStencilSpotLights(RasterCommandBuffer cmd, bool stripShadowsOffVarian
10321027

10331028
isFirstLight = false;
10341029
}
1035-
10361030
cmd.SetKeyword(ShaderGlobalKeywords._SPOT, false);
10371031
}
10381032

Packages/com.unity.render-pipelines.universal/Runtime/Passes/AdditionalLightsShadowAtlasLayout.cs

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -339,7 +339,7 @@ static int EstimateScaleFactorNeededToFitAllShadowsInAtlas(in NativeArray<Shadow
339339
}
340340

341341
// Sort array in decreasing requestedResolution order,
342-
// sub-sorting in "HardShadow > SoftShadow" and then "Spot > Point",
342+
// sub-sorting in "HardShadow > SoftShadow",
343343
// i.e place last requests that will be removed in priority to make room for the others,
344344
// because their resolution is too small to produce good-looking shadows ; or because they take relatively more space in the atlas )
345345
// sub-sub-sorting in light distance to camera
@@ -350,10 +350,9 @@ static Func<ShadowResolutionRequest, ShadowResolutionRequest, int> CreateCompare
350350
{
351351
return (((curr.requestedResolution > other.requestedResolution)
352352
|| (curr.requestedResolution == other.requestedResolution && !curr.softShadow && other.softShadow)
353-
|| (curr.requestedResolution == other.requestedResolution && curr.softShadow == other.softShadow && !curr.pointLightShadow && other.pointLightShadow)
354-
|| (curr.requestedResolution == other.requestedResolution && curr.softShadow == other.softShadow && curr.pointLightShadow == other.pointLightShadow && s_VisibleLightIndexToCameraSquareDistance[curr.visibleLightIndex] < s_VisibleLightIndexToCameraSquareDistance[other.visibleLightIndex])
355-
|| (curr.requestedResolution == other.requestedResolution && curr.softShadow == other.softShadow && curr.pointLightShadow == other.pointLightShadow && s_VisibleLightIndexToCameraSquareDistance[curr.visibleLightIndex] == s_VisibleLightIndexToCameraSquareDistance[other.visibleLightIndex] && curr.visibleLightIndex < other.visibleLightIndex)
356-
|| (curr.requestedResolution == other.requestedResolution && curr.softShadow == other.softShadow && curr.pointLightShadow == other.pointLightShadow && s_VisibleLightIndexToCameraSquareDistance[curr.visibleLightIndex] == s_VisibleLightIndexToCameraSquareDistance[other.visibleLightIndex] && curr.visibleLightIndex == other.visibleLightIndex && curr.perLightShadowSliceIndex < other.perLightShadowSliceIndex)))
353+
|| (curr.requestedResolution == other.requestedResolution && curr.softShadow == other.softShadow && s_VisibleLightIndexToCameraSquareDistance[curr.visibleLightIndex] < s_VisibleLightIndexToCameraSquareDistance[other.visibleLightIndex])
354+
|| (curr.requestedResolution == other.requestedResolution && curr.softShadow == other.softShadow && s_VisibleLightIndexToCameraSquareDistance[curr.visibleLightIndex] == s_VisibleLightIndexToCameraSquareDistance[other.visibleLightIndex] && curr.visibleLightIndex < other.visibleLightIndex)
355+
|| (curr.requestedResolution == other.requestedResolution && curr.softShadow == other.softShadow && s_VisibleLightIndexToCameraSquareDistance[curr.visibleLightIndex] == s_VisibleLightIndexToCameraSquareDistance[other.visibleLightIndex] && curr.visibleLightIndex == other.visibleLightIndex && curr.perLightShadowSliceIndex < other.perLightShadowSliceIndex)))
357356
? -1 : 1;
358357
};
359358
}

0 commit comments

Comments
 (0)