Skip to content

Commit 0ba9c99

Browse files
Contact shadows improvements (#1226)
* Bias + thickness + new depth compare * Default as decided by pierre * upgrade guide * docs * changelog * What's new
1 parent 0fa339e commit 0ba9c99

File tree

10 files changed

+47
-8
lines changed

10 files changed

+47
-8
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -159,6 +159,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.
159159
- Added an option to extend the camera culling for skinned mesh animation in ray tracing effects (1258547).
160160
- Added decal layer system similar to light layer. Mesh will receive a decal when both decal layer mask matches.
161161
- Added shader graph nodes for rendering a complex eye shader.
162+
- Added more controls to contact shadows and increased quality in some parts.
162163

163164
### Fixed
164165
- Fix when rescale probe all direction below zero (1219246)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ Only one Light can cast Contact Shadows at a time. This means that, if you have
3131
| __Fade Out Distance__ | The distance, in meters, over which HDRP fades Contact Shadows out when at the __Max Distance__. |
3232
| __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. |
3333
| __Opacity__ | Use the slider to set the opacity of the Contact Shadows. Lower values result in softer, less prominent shadows. |
34+
| **Ray Bias** | Controls the bias applied to the screen space ray cast to get contact shadows. Higher values can reduce self shadowing, however too high values might lead to peter-panning that can be especially undesirable with contact shadows. |
35+
| **Thickness** | Controls the thickness of the objects found along the ray, essentially thickening the contact shadows. It can be used to fill holes in the shadows, however might also lead to overly wide shadows. |
3436

3537
## Details
3638

com.unity.render-pipelines.high-definition/Documentation~/Upgrading-from-2020.1-to-2020.2.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ HDRP now stores OnEnable and OnDemand shadows in a separate atlas and more API i
5050

5151
The shader function `SampleShadow_PCSS` now requires you to pass in an additional float2 parameter which contains the shadow atlas resolution in x and the inverse of the atlas resolution in y.
5252

53+
Ray bias and thickness parameters have been added to contact shadows. These might lead to small changes to the visual impact of contact shadows with the default parameters. Please consider tuning those values to fit the needs of your project.
54+
5355
## Shader config file
5456

5557
From Unity 2020.2, due to the change of the shadow map, HDRP moved the HDShadowFilteringQuality enum to HDShadowManager.cs. HDRP also removed ShaderConfig.s_DeferredShadowFiltering and ShaderOptions.DeferredShadowFiltering from the source code because they have no effect anymore.

com.unity.render-pipelines.high-definition/Documentation~/whats-new-10-0.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,10 @@ You can now control the texture mapping mode for all textures in the [AxF Shader
247247

248248
For more information about this improvement, see [AxF Shader](AxF-Shader.md).
249249

250+
### Contact Shadows Improvements
251+
252+
More control is given for contact shadows, in particular now a bias can be set to avoid self intersection issues and a new thickness parameter is introduced to fill gaps that can be left by contact shadows.
253+
250254
### Exposure
251255

252256
#### Exposure curve mapping

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ class ContactShadowsEditor : VolumeComponentWithQualityEditor
1616
SerializedDataParameter m_FadeInDistance;
1717
SerializedDataParameter m_SampleCount;
1818
SerializedDataParameter m_Opacity;
19+
SerializedDataParameter m_Bias;
20+
SerializedDataParameter m_Thickness;
1921

2022
public override void OnEnable()
2123
{
@@ -32,6 +34,8 @@ public override void OnEnable()
3234
m_FadeInDistance = Unpack(o.Find(x => x.fadeInDistance));
3335
m_SampleCount = Unpack(o.Find(x => x.sampleCount));
3436
m_Opacity = Unpack(o.Find(x => x.opacity));
37+
m_Bias = Unpack(o.Find(x => x.rayBias));
38+
m_Thickness = Unpack(o.Find(x => x.thicknessScale));
3539
}
3640

3741
public override void OnInspectorGUI()
@@ -49,6 +53,9 @@ public override void OnInspectorGUI()
4953
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."));
5054
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."));
5155
PropertyField(m_Opacity, EditorGUIUtility.TrTextContent("Opacity", "Controls the opacity of the Contact Shadow."));
56+
PropertyField(m_Bias, EditorGUIUtility.TrTextContent("Bias", "Controls the bias applied to the screen space ray cast to get contact shadows."));
57+
PropertyField(m_Thickness, EditorGUIUtility.TrTextContent("Thickness", "Controls the thickness of the objects found along the ray, essentially thickening the contact shadows."));
58+
5259
base.OnInspectorGUI();
5360
GUI.enabled = useCustomValue;
5461
PropertyField(m_SampleCount, EditorGUIUtility.TrTextContent("Sample Count", "Controls the number of samples HDRP uses for ray casting."));

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

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3717,7 +3717,7 @@ struct ContactShadowsParameters
37173717

37183718
public Vector4 params1;
37193719
public Vector4 params2;
3720-
public int sampleCount;
3720+
public Vector4 params3;
37213721

37223722
public int numTilesX;
37233723
public int numTilesY;
@@ -3762,8 +3762,8 @@ ContactShadowsParameters PrepareContactShadowsParameters(HDCamera hdCamera, floa
37623762
float contactShadowFadeIn = Mathf.Clamp(m_ContactShadows.fadeInDistance.value, 1e-6f, contactShadowFadeEnd);
37633763

37643764
parameters.params1 = new Vector4(m_ContactShadows.length.value, m_ContactShadows.distanceScaleFactor.value, contactShadowFadeEnd, contactShadowOneOverFadeRange);
3765-
parameters.params2 = new Vector4(firstMipOffsetY, contactShadowMinDist, contactShadowFadeIn, 0.0f);
3766-
parameters.sampleCount = m_ContactShadows.sampleCount;
3765+
parameters.params2 = new Vector4(firstMipOffsetY, contactShadowMinDist, contactShadowFadeIn, m_ContactShadows.rayBias.value * 0.01f);
3766+
parameters.params3 = new Vector4(m_ContactShadows.sampleCount, m_ContactShadows.thicknessScale.value * 10.0f , 0.0f, 0.0f);
37673767

37683768
int deferredShadowTileSize = 16; // Must match DeferreDirectionalShadow.compute
37693769
parameters.numTilesX = (hdCamera.actualWidth + (deferredShadowTileSize - 1)) / deferredShadowTileSize;
@@ -3786,7 +3786,7 @@ static void RenderContactShadows( in ContactShadowsParameters parameters,
37863786

37873787
cmd.SetComputeVectorParam(parameters.contactShadowsCS, HDShaderIDs._ContactShadowParamsParameters, parameters.params1);
37883788
cmd.SetComputeVectorParam(parameters.contactShadowsCS, HDShaderIDs._ContactShadowParamsParameters2, parameters.params2);
3789-
cmd.SetComputeIntParam(parameters.contactShadowsCS, HDShaderIDs._DirectionalContactShadowSampleCount, parameters.sampleCount);
3789+
cmd.SetComputeVectorParam(parameters.contactShadowsCS, HDShaderIDs._ContactShadowParamsParameters3, parameters.params3);
37903790
cmd.SetComputeBufferParam(parameters.contactShadowsCS, parameters.kernel, HDShaderIDs._DirectionalLightDatas, lightLoopLightData.directionalLightData);
37913791

37923792
// Send light list to the compute

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

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,16 @@ float SampleDepth(float2 UV, bool HalfRes)
4141
return LoadCameraDepth(pixelCoord);
4242
}
4343

44+
float GetDepthCompareThreshold(float step, float rayStartZ, float rayOrthoZ)
45+
{
46+
return abs(rayOrthoZ - rayStartZ) * _ContactShadowThickness * max(0.07, step);
47+
}
48+
49+
bool CompareDepth(float depthDiff, float compareThreshold)
50+
{
51+
return abs(compareThreshold - depthDiff) < compareThreshold;
52+
}
53+
4454

4555
bool ScreenSpaceShadowRayCast(float3 positionWS, float3 rayDirWS, float rayLength, uint2 positionSS, out float fade)
4656
{
@@ -50,7 +60,7 @@ bool ScreenSpaceShadowRayCast(float3 positionWS, float3 rayDirWS, float rayLengt
5060
uint taaEnabled = _TaaFrameInfo.w;
5161
float dither = InterleavedGradientNoise(positionSS, (_FrameCount % 8u) * taaEnabled) - ditherBias;
5262

53-
float3 rayStartWS = positionWS;
63+
float3 rayStartWS = positionWS - positionWS * _ContactShadowBias;
5464
float3 rayEndWS = rayStartWS + rayDirWS * rayLength;
5565

5666
float4 rayStartCS = TransformWorldToHClip(rayStartWS);
@@ -68,7 +78,7 @@ bool ScreenSpaceShadowRayCast(float3 positionWS, float3 rayDirWS, float rayLengt
6878
float3 rayDirCS = rayEndCS.xyz - rayStartCS.xyz;
6979

7080
float step = 1.0f / _SampleCount;
71-
float compareThreshold = abs(rayOrthoViewSpace.z - rayStartCS.z) * max(0.07f, step);
81+
float compareThreshold = GetDepthCompareThreshold(step, rayStartCS.z, rayOrthoViewSpace.z);
7282

7383
float occluded = 0.0f;
7484

@@ -107,7 +117,7 @@ bool ScreenSpaceShadowRayCast(float3 positionWS, float3 rayDirWS, float rayLengt
107117

108118
float depthDiff = sampleDepth - sampleAlongRay.z;
109119

110-
if (depthDiff > 0.0f && depthDiff < compareThreshold && sampleAlongRay.z > 0)
120+
if (depthDiff > 0.0f && CompareDepth(depthDiff, compareThreshold) && sampleAlongRay.z > 0)
111121
{
112122
if (tracingHalfRes)
113123
{

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,8 +43,16 @@ public class ContactShadows : VolumeComponentWithQuality
4343
/// </summary>
4444
public MinFloatParameter fadeInDistance = new MinFloatParameter(0.0f, 0.0f);
4545
/// <summary>
46-
/// Controls the number of samples HDRP takes along each contact shadow ray. Increasing this value can lead to higher quality.
46+
/// Controls the bias applied to the screen space ray cast to get contact shadows.
4747
/// </summary>
48+
public ClampedFloatParameter rayBias = new ClampedFloatParameter(0.2f, 0.0f, 1.0f);
49+
/// <summary>
50+
/// Controls the thickness of the objects found along the ray, essentially thickening the contact shadows.
51+
/// </summary>
52+
public ClampedFloatParameter thicknessScale = new ClampedFloatParameter(0.15f, 0.02f, 1.0f);
53+
54+
55+
4856
public int sampleCount
4957
{
5058
get

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ RW_TEXTURE2D_X(uint, _ContactShadowTextureUAV);
33
CBUFFER_START(DeferredShadowParameters)
44
float4 _ContactShadowParamsParameters;
55
float4 _ContactShadowParamsParameters2;
6+
float4 _ContactShadowParamsParameters3;
67
int _SampleCount;
78
CBUFFER_END
89

@@ -13,3 +14,6 @@ CBUFFER_END
1314
#define _RenderTargetHeight _ContactShadowParamsParameters2.x
1415
#define _ContactShadowMinDistance _ContactShadowParamsParameters2.y
1516
#define _ContactShadowFadeInEnd _ContactShadowParamsParameters2.z
17+
#define _ContactShadowBias _ContactShadowParamsParameters2.w
18+
#define _SampleCount (int)_ContactShadowParamsParameters3.x
19+
#define _ContactShadowThickness _ContactShadowParamsParameters3.y

com.unity.render-pipelines.high-definition/Runtime/RenderPipeline/HDStringConstants.cs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ static class HDShaderIDs
179179
public static readonly int _ContactShadowTextureUAV = Shader.PropertyToID("_ContactShadowTextureUAV");
180180
public static readonly int _ContactShadowParamsParameters = Shader.PropertyToID("_ContactShadowParamsParameters");
181181
public static readonly int _ContactShadowParamsParameters2 = Shader.PropertyToID("_ContactShadowParamsParameters2");
182+
public static readonly int _ContactShadowParamsParameters3 = Shader.PropertyToID("_ContactShadowParamsParameters3");
182183
public static readonly int _DirectionalContactShadowSampleCount = Shader.PropertyToID("_SampleCount");
183184
public static readonly int _ShadowFrustumPlanes = Shader.PropertyToID("_ShadowFrustumPlanes");
184185

0 commit comments

Comments
 (0)