Skip to content

Commit 5ddc82d

Browse files
FrancescoC-unitysebastienlagarde
authored andcommitted
Contact shadow min distance + fix scalarization code #150
1 parent a692cd5 commit 5ddc82d

File tree

8 files changed

+61
-24
lines changed

8 files changed

+61
-24
lines changed

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
1616
- Added Light decomposition lighting debugging modes and support in AOV
1717
- Added exposure compensation to Fixed exposure mode
1818
- Added range attenuation for box-shaped spotlights.
19+
- Added Min distance to contact shadows.
1920

2021
### Fixed
2122
- Fixed an issue where a dynamic sky changing any frame may not update the ambient probe.
@@ -62,7 +63,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
6263
- Fixed shader warning on Xbox for ResolveStencilBuffer.compute.
6364
- Fixed unneeded cookie texture allocation for cone stop lights.
6465
- Fixed issue when toggling anything in HDRP asset that will produce an error (case 1238155)
65-
- Diffusion Profile and Material references in HDRP materials are now correctly exported to unity packages. Note that the diffusion profile or the material references need to be edited once before this can work properly.
66+
- Fixed scalarization code for contact shadows
6667

6768
### Changed
6869
- Rejecting history for ray traced reflections based on a threshold evaluated on the neighborhood of the sampled history.
@@ -74,6 +75,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
7475
- Renamed "Environment" to "Reflection Probes" in tile/cluster debug menu.
7576
- Debug exposure in debug menu have been replace to debug exposure compensation in EV100 space and is always visible.
7677
- Cookie are now supported in lightmaper. All lights casting cookie and baked will now include cookie influence.
78+
- Diffusion Profile and Material references in HDRP materials are now correctly exported to unity packages. Note that the diffusion profile or the material references need to be edited once before this can work properly.
7779

7880
## [8.0.1] - 2020-02-25
7981

Lines changed: 2 additions & 2 deletions
Loading

com.unity.render-pipelines.high-definition/Documentation~/Override-Contact-Shadows.md

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,10 @@ Only one Light can cast Contact Shadows at a time. This means that, if you have
2525
| __Enable__ | Enable the checkbox to make HDRP process Contact Shadows for this [Volume](Volumes.html). |
2626
| __Length__ | Use the slider to set the length of the rays, in meters, that HDRP uses for tracing. It also functions as the maximum distance at which the rays can captures details. |
2727
| __Distance Scale Factor__ | HDRP scales Contact Shadows up with distance. Use the slider to set the value that HDRP uses to dampen the scale to avoid biasing artifacts with distance. |
28+
| __Min Distance__ | The distance from the Camera, in meters, at which HDRP begins to fade in Contact Shadows. |
2829
| __Max Distance__ | The distance from the Camera, in meters, at which HDRP begins to fade Contact Shadows out to zero. |
29-
| __Fade Distance__ | The distance, in meters, over which HDRP fades Contact Shadows out when at the __Max Distance__. |
30+
| __Fade In Distance__ | The distance, in meters, over which HDRP fades Contact Shadows in when past the **Min Distance**. |
31+
| __Fade Out Distance__ | The distance, in meters, over which HDRP fades Contact Shadows out when at the __Max Distance__. |
3032
| __Sample Count__ | Use the slider to set the number of samples HDRP uses for ray casting. Increasing this increases quality at the cost of performance. |
3133
| __Opacity__ | Use the slider to set the opacity of the Contact Shadows. Lower values result in softer, less prominent shadows. |
3234

com.unity.render-pipelines.high-definition/Editor/Lighting/Shadow/ContactShadowsEditor.cs

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,11 +11,12 @@ class ContactShadowsEditor : VolumeComponentWithQualityEditor
1111
SerializedDataParameter m_Length;
1212
SerializedDataParameter m_DistanceScaleFactor;
1313
SerializedDataParameter m_MaxDistance;
14+
SerializedDataParameter m_MinDistance;
1415
SerializedDataParameter m_FadeDistance;
16+
SerializedDataParameter m_FadeInDistance;
1517
SerializedDataParameter m_SampleCount;
1618
SerializedDataParameter m_Opacity;
1719

18-
1920
public override void OnEnable()
2021
{
2122
base.OnEnable();
@@ -26,7 +27,9 @@ public override void OnEnable()
2627
m_Length = Unpack(o.Find(x => x.length));
2728
m_DistanceScaleFactor = Unpack(o.Find(x => x.distanceScaleFactor));
2829
m_MaxDistance = Unpack(o.Find(x => x.maxDistance));
30+
m_MinDistance = Unpack(o.Find(x => x.minDistance));
2931
m_FadeDistance = Unpack(o.Find(x => x.fadeDistance));
32+
m_FadeInDistance = Unpack(o.Find(x => x.fadeInDistance));
3033
m_SampleCount = Unpack(o.Find(x => x.sampleCount));
3134
m_Opacity = Unpack(o.Find(x => x.opacity));
3235
}
@@ -41,8 +44,12 @@ public override void OnInspectorGUI()
4144
{
4245
PropertyField(m_Length, EditorGUIUtility.TrTextContent("Length", "Controls the length of the rays HDRP uses to calculate Contact Shadows. Uses meters."));
4346
PropertyField(m_DistanceScaleFactor, EditorGUIUtility.TrTextContent("Distance Scale Factor", "Dampens the scale up effect HDRP process with distance from the Camera."));
44-
PropertyField(m_MaxDistance, EditorGUIUtility.TrTextContent("Max Distance", "Sets The distance from the Camera at which HDRP begins to fade out Contact Shadows. Uses meters."));
45-
PropertyField(m_FadeDistance, EditorGUIUtility.TrTextContent("Fade Distance", "Sets the distance over which HDRP fades Contact Shadows out when at the Max Distance. Uses meters."));
47+
m_MinDistance.value.floatValue = Mathf.Clamp(m_MinDistance.value.floatValue, 0.0f, m_MaxDistance.value.floatValue);
48+
PropertyField(m_MinDistance, EditorGUIUtility.TrTextContent("Min Distance", "Sets the distance from the camera at which HDRP begins to fade in Contact Shadows. Uses meters."));
49+
PropertyField(m_MaxDistance, EditorGUIUtility.TrTextContent("Max Distance", "Sets the distance from the Camera at which HDRP begins to fade out Contact Shadows. Uses meters."));
50+
m_FadeInDistance.value.floatValue = Mathf.Clamp(m_FadeInDistance.value.floatValue, 0.0f, m_MaxDistance.value.floatValue);
51+
PropertyField(m_FadeInDistance, EditorGUIUtility.TrTextContent("Fade In Distance", "Sets the distance over which HDRP fades Contact Shadows in when past the Min Distance. Uses meters."));
52+
PropertyField(m_FadeDistance, EditorGUIUtility.TrTextContent("Fade Out Distance", "Sets the distance over which HDRP fades Contact Shadows out when at the Max Distance. Uses meters."));
4653
PropertyField(m_Opacity, EditorGUIUtility.TrTextContent("Opacity", "Controls the opacity of the Contact Shadow."));
4754
base.OnInspectorGUI();
4855
GUI.enabled = useCustomValue;

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3447,8 +3447,12 @@ ContactShadowsParameters PrepareContactShadowsParameters(HDCamera hdCamera, floa
34473447
float contactShadowRange = Mathf.Clamp(m_ContactShadows.fadeDistance.value, 0.0f, m_ContactShadows.maxDistance.value);
34483448
float contactShadowFadeEnd = m_ContactShadows.maxDistance.value;
34493449
float contactShadowOneOverFadeRange = 1.0f / Math.Max(1e-6f, contactShadowRange);
3450+
3451+
float contactShadowMinDist = Mathf.Min(m_ContactShadows.minDistance.value, contactShadowFadeEnd);
3452+
float contactShadowFadeIn = Mathf.Clamp(m_ContactShadows.fadeInDistance.value, 1e-6f, contactShadowFadeEnd);
3453+
34503454
parameters.params1 = new Vector4(m_ContactShadows.length.value, m_ContactShadows.distanceScaleFactor.value, contactShadowFadeEnd, contactShadowOneOverFadeRange);
3451-
parameters.params2 = new Vector4(firstMipOffsetY, 0.0f, 0.0f, 0.0f);
3455+
parameters.params2 = new Vector4(firstMipOffsetY, contactShadowMinDist, contactShadowFadeIn, 0.0f);
34523456
parameters.sampleCount = m_ContactShadows.sampleCount;
34533457

34543458
int deferredShadowTileSize = 16; // Must match DeferreDirectionalShadow.compute

com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/ContactShadows.compute

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,9 @@
1515
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/LightLoop/LightLoopDef.hlsl"
1616
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/Lighting/Shadow/ContactShadows.hlsl"
1717

18-
// We perform scalarization only for forward rendering as for deferred loads will already be scalar since tiles will match waves and therefore all threads will read from the same tile.
18+
// We perform scalarization all the time here as we don't know if we have clustered data structure or not at this point.
1919
// More info on scalarization: https://flashypixels.wordpress.com/2018/11/10/intro-to-gpu-scalarization-part-2-scalarize-all-the-lights/
20-
#define SCALARIZE_LIGHT_LOOP (defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS) && !defined(LIGHTLOOP_DISABLE_TILE_AND_CLUSTER) && SHADERPASS == SHADERPASS_FORWARD)
20+
#define SCALARIZE_LIGHT_LOOP (defined(PLATFORM_SUPPORTS_WAVE_INTRINSICS) && !defined(LIGHTLOOP_DISABLE_TILE_AND_CLUSTER))
2121

2222
#pragma only_renderers d3d11 playstation xboxone vulkan metal switch
2323

@@ -147,6 +147,9 @@ bool ComputeContactShadow(PositionInputs posInput, float3 direction, inout float
147147
//Here LightDirection is not the light direction but the light position
148148
float rayLength = _ContactShadowLength * max(0.5, posInput.linearDepth * _ContactShadowDistanceScaleFactor);
149149
occluded = ScreenSpaceShadowRayCast(posInput.positionWS, direction, rayLength, posInput.positionSS, fade);
150+
// Fade in
151+
fade *= saturate((posInput.linearDepth - _ContactShadowMinDistance) * rcp(_ContactShadowFadeInEnd));
152+
// Fade out
150153
fade *= saturate((_ContactShadowFadeEnd - posInput.linearDepth) * _ContactShadowFadeOneOverRange);
151154

152155
globalFade = max(globalFade, fade);
@@ -172,7 +175,7 @@ void DEFERRED_CONTACT_SHADOW_GENERIC(uint2 groupThreadId : SV_GroupThreadID, uin
172175
PositionInputs posInput = GetPositionInput(pixelCoord.xy, _ScreenSize.zw, depth, UNITY_MATRIX_I_VP, UNITY_MATRIX_V, tileCoord);
173176

174177
// discard the shadow if we're on the sky or outside of the contact shadow range
175-
if (depth == UNITY_RAW_FAR_CLIP_VALUE || posInput.linearDepth - _ContactShadowFadeEnd > 1)
178+
if (depth == UNITY_RAW_FAR_CLIP_VALUE || posInput.linearDepth - _ContactShadowFadeEnd > 1 || posInput.linearDepth < _ContactShadowMinDistance)
176179
{
177180
_ContactShadowTextureUAV[COORD_TEXTURE2D_X(pixelCoord)] = 0;
178181

@@ -228,26 +231,35 @@ void DEFERRED_CONTACT_SHADOW_GENERIC(uint2 groupThreadId : SV_GroupThreadID, uin
228231
lightStart = startFirstLane;
229232
}
230233

231-
for (uint lightListOffset = 0; lightListOffset < lightCount; lightListOffset++)
234+
uint v_lightIdx = lightStart;
235+
uint v_lightListOffset = 0;
236+
while (v_lightListOffset < lightCount)
232237
{
233-
uint v_lightIdx = FetchIndex(lightStart, lightListOffset);
238+
v_lightIdx = FetchIndex(lightStart, v_lightListOffset);
234239
uint s_lightIdx = ScalarizeElementIndex(v_lightIdx, fastPath);
235240
if (s_lightIdx == -1)
236241
break;
237242

238-
LightData light = FetchLight(s_lightIdx); // Scalar load
243+
LightData s_lightData = FetchLight(s_lightIdx);
239244

240-
if (light.contactShadowMask != 0 && light.isRayTracedContactShadow == 0.0)
245+
// If current scalar and vector light index match, we process the light. The v_lightListOffset for current thread is increased.
246+
// Note that the following should really be ==, however, since helper lanes are not considered by WaveActiveMin, such helper lanes could
247+
// end up with a unique v_lightIdx value that is smaller than s_lightIdx hence being stuck in a loop. All the active lanes will not have this problem.
248+
if (s_lightIdx >= v_lightIdx)
241249
{
242-
// Compute light ray direction:
243-
float3 direction = normalize(light.positionRWS.xyz - posInput.positionWS);
244-
245-
bool occluded = ComputeContactShadow(posInput, direction, globalFade);
246-
247-
// light.contactShadowMask contains one bit at the position of the contact shadow index that will
248-
// be tested in the lightloop, so it insert 1 at the index of the contact shadow if there is a contact shadow
249-
// we take full bits at one multiplied by contact shadow and filter the bit at the contact shadow index.
250-
contactShadowMask |= light.contactShadowMask * occluded;
250+
v_lightListOffset++;
251+
if (s_lightData.contactShadowMask != 0 && s_lightData.isRayTracedContactShadow == 0.0)
252+
{
253+
// Compute light ray direction:
254+
float3 direction = normalize(s_lightData.positionRWS.xyz - posInput.positionWS);
255+
256+
bool occluded = ComputeContactShadow(posInput, direction, globalFade);
257+
258+
// light.contactShadowMask contains one bit at the position of the contact shadow index that will
259+
// be tested in the lightloop, so it insert 1 at the index of the contact shadow if there is a contact shadow
260+
// we take full bits at one multiplied by contact shadow and filter the bit at the contact shadow index.
261+
contactShadowMask |= s_lightData.contactShadowMask * occluded;
262+
}
251263
}
252264
}
253265
}

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

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,18 @@ public class ContactShadows : VolumeComponentWithQuality
3131
/// </summary>
3232
public MinFloatParameter maxDistance = new MinFloatParameter(50.0f, 0.0f);
3333
/// <summary>
34+
/// The distance from the camera, in meters, at which HDRP begins to fade in Contact Shadows.
35+
/// </summary>
36+
public MinFloatParameter minDistance = new MinFloatParameter(0.0f, 0.0f);
37+
/// <summary>
3438
/// The distance, in meters, over which HDRP fades Contact Shadows out when past the Max Distance.
3539
/// </summary>
3640
public MinFloatParameter fadeDistance = new MinFloatParameter(5.0f, 0.0f);
3741
/// <summary>
42+
/// The distance, in meters, over which HDRP fades Contact Shadows in when past the Min Distance.
43+
/// </summary>
44+
public MinFloatParameter fadeInDistance = new MinFloatParameter(0.0f, 0.0f);
45+
/// <summary>
3846
/// Controls the number of samples HDRP takes along each contact shadow ray. Increasing this value can lead to higher quality.
3947
/// </summary>
4048
public int sampleCount

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,3 +11,5 @@ CBUFFER_END
1111
#define _ContactShadowFadeEnd _ContactShadowParamsParameters.z
1212
#define _ContactShadowFadeOneOverRange _ContactShadowParamsParameters.w
1313
#define _RenderTargetHeight _ContactShadowParamsParameters2.x
14+
#define _ContactShadowMinDistance _ContactShadowParamsParameters2.y
15+
#define _ContactShadowFadeInEnd _ContactShadowParamsParameters2.z

0 commit comments

Comments
 (0)