Skip to content

Commit 6878230

Browse files
Fix shadow mask fade and optimize it at same time #5911
1 parent f549e27 commit 6878230

File tree

5 files changed

+32
-13
lines changed

5 files changed

+32
-13
lines changed

com.unity.render-pipelines.high-definition/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
3333
- Fixed compatibility message not displayed correctly when switching platforms.
3434
- Fixed support for interleaved tiling in path tracing.
3535
- Fixed robustness issues with the stacklit material in path tracing (case 1373971).
36+
- Fixed and optimize distance shadowmask fade.
3637

3738
### Changed
3839
- Use RayTracingAccelerationStructure.CullInstances to filter Renderers and populate the acceleration structure with ray tracing instances for improved CPU performance on the main thread.

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

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,12 @@ internal struct CreateGpuLightDataJob : IJobParallelFor
7676
public Vector3 airExtinctionCoefficient;
7777
[ReadOnly]
7878
public float aerosolExtinctionCoefficient;
79+
[ReadOnly]
80+
public float maxShadowDistance;
81+
[ReadOnly]
82+
public float shadowOutBorderDistance;
83+
84+
7985
#endregion
8086

8187
#region input light entity data
@@ -321,6 +327,21 @@ public static void ConvertLightToGPUFormat(
321327
{
322328
lightData.shadowMaskSelector[visibleLightBakingOutput.occlusionMaskChannel] = 1.0f;
323329
lightData.nonLightMappedOnly = visibleLightShadowCasterMode == LightShadowCasterMode.NonLightmappedOnly ? 1 : 0;
330+
// Get shadow info from the volume stack.
331+
float maxDistanceSq = maxShadowDistance * maxShadowDistance;
332+
float outBorderDistance = shadowOutBorderDistance;
333+
if (outBorderDistance < 1e-4f)
334+
{
335+
lightData.cascadesBorderFadeScaleBias = new Vector2(1e6f, -maxDistanceSq * 1e6f);
336+
}
337+
else
338+
{
339+
outBorderDistance = 1.0f - outBorderDistance;
340+
outBorderDistance *= outBorderDistance;
341+
float distanceFadeNear = outBorderDistance * maxDistanceSq;
342+
lightData.cascadesBorderFadeScaleBias.x = 1.0f / (maxDistanceSq - distanceFadeNear);
343+
lightData.cascadesBorderFadeScaleBias.y = -distanceFadeNear / (maxDistanceSq - distanceFadeNear);
344+
}
324345
}
325346
else
326347
{
@@ -692,6 +713,7 @@ public void StartCreateGpuLightDataJob(
692713
{
693714
var visualEnvironment = hdCamera.volumeStack.GetComponent<VisualEnvironment>();
694715
var skySettings = hdCamera.volumeStack.GetComponent<PhysicallyBasedSky>();
716+
var shadowSettings = hdCamera.volumeStack.GetComponent<HDShadowSettings>();
695717
Debug.Assert(visualEnvironment != null);
696718
bool isPbrSkyActive = visualEnvironment.skyType.value == (int)SkyType.PhysicallyBased;
697719

@@ -718,6 +740,9 @@ public void StartCreateGpuLightDataJob(
718740
airExtinctionCoefficient = skySettings.GetAirExtinctionCoefficient(),
719741
aerosolExtinctionCoefficient = skySettings.GetAerosolExtinctionCoefficient(),
720742

743+
maxShadowDistance = shadowSettings.maxShadowDistance.value,
744+
shadowOutBorderDistance = shadowSettings.cascadeShadowBorders[shadowSettings.cascadeShadowSplitCount.value - 1],
745+
721746
// light entity data
722747
lightRenderDataArray = lightEntities.lightData,
723748

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,8 @@ struct DirectionalLightData
9595
[SurfaceDataAttributes(precision = FieldPrecision.Real)]
9696
public Vector4 shadowMaskSelector; // Used with ShadowMask feature
9797

98+
public Vector2 cascadesBorderFadeScaleBias;
99+
98100
public float diffuseDimmer;
99101
public float specularDimmer;
100102
public float penumbraTint;

com.unity.render-pipelines.high-definition/Runtime/Lighting/LightDefinition.cs.hlsl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ struct DirectionalLightData
7272
real minRoughness;
7373
int screenSpaceShadowIndex;
7474
real4 shadowMaskSelector;
75+
float2 cascadesBorderFadeScaleBias;
7576
float diffuseDimmer;
7677
float specularDimmer;
7778
float penumbraTint;

com.unity.render-pipelines.high-definition/Runtime/Lighting/LightEvaluation.hlsl

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -269,19 +269,9 @@ SHADOW_TYPE EvaluateShadow_Directional( LightLoopContext lightLoopContext, Posit
269269
shadow = lightLoopContext.shadowValue;
270270

271271
#ifdef SHADOWS_SHADOWMASK
272-
// TODO: Optimize this code! Currently it is a bit like brute force to get the last transistion and fade to shadow mask, but there is
273-
// certainly more efficient to do
274-
// We reuse the transition from the cascade system to fade between shadow mask at max distance
275-
uint payloadOffset;
276-
real fade;
277-
int cascadeCount;
278-
int shadowSplitIndex = 0;
279-
280-
shadowSplitIndex = EvalShadow_GetSplitIndex(lightLoopContext.shadowContext, light.shadowIndex, posInput.positionWS, fade, cascadeCount);
281-
282-
// we have a fade caclulation for each cascade but we must lerp with shadow mask only for the last one
283-
// if shadowSplitIndex is -1 it mean we are outside cascade and should return 1.0 to use shadowmask: saturate(-shadowSplitIndex) return 0 for >= 0 and 1 for -1
284-
fade = ((shadowSplitIndex + 1) == cascadeCount) ? fade : saturate(-shadowSplitIndex);
272+
float3 camToPixel = posInput.positionWS - GetPrimaryCameraPosition();
273+
float distanceCamToPixel2 = dot(camToPixel, camToPixel);
274+
float fade = saturate(distanceCamToPixel2 * light.cascadesBorderFadeScaleBias.x + light.cascadesBorderFadeScaleBias.y);
285275

286276
// In the transition code (both dithering and blend) we use shadow = lerp( shadow, 1.0, fade ) for last transition
287277
// mean if we expend the code we have (shadow * (1 - fade) + fade). Here to make transition with shadow mask

0 commit comments

Comments
 (0)