Skip to content

Universal/point light shadows#1616

Merged
ellioman merged 68 commits into
masterfrom
universal/point-light-shadows
Nov 30, 2020
Merged

Universal/point light shadows#1616
ellioman merged 68 commits into
masterfrom
universal/point-light-shadows

Conversation

@Wilfrid-Unity

Copy link
Copy Markdown
Contributor

Purpose of this PR

This pull request adds support for real-time Point Light shadows in Universal RP, as well as some fixes for Universal RP real-time shadows.
It brings Unity's Universal RP closer to parity with the Built-In RP.

Main changes

Point Light shadows are implemented by extending pre-existing class UnityEngine.Rendering.Universal.Internal.AdditionalLightsShadowCasterPass, that was previously used only for Spot Lights shadows.

In Unity code the term "shadow slice" is used to refer to shadow map textures generated for a single shadow casting light.
While a Spot Lights only require 1 shadow slice, for Point Lights 6 shadow slices are needed (one for each face of a cube around the light).
Therefore the main changes in this pull request are related to the indexing of those additional shadow slices.

Other additions from this pull request

  • When applying Punctual Lights Shadow Normal Bias, the light direction used is taken separately for each different shadow caster vertex position. Previously, the same light direction was used for all vertices, which caused the shape of shadows to change when a point light was rotated.

  • Punctual light shadow setting "Soft Shadow" or "Hard Shadow" can now be set independently for each light. Previously, assigning "Soft Shadows" to one punctual light in the scene forced all shadow-casting punctual lights in the scene to use the "Soft Shadows" setting.

  • The number of shadow casters rendered when generating spot light shadow maps is reduced. Previously, culling settings caused excess casters to be rendered, with an impact on perfomance.

Not addressed by this pull request

  • Per-light shadow resolution override is not implemented by this pull request. It will be added separately.

Testing status

Manual Tests:
I manually verified that punctual light shadows work in several scenarios combining multiple types of lights and shadow settings.
I manually verified that point light shadows were correctly rendered when using the Deferred Renderer.
I manually verified that point light shadows were correctly rendered when using Structured Buffers instead of Uniform Buffers, to pass shadow information to the GPU during the Lighting pass.

Automated Tests:
This pull request adds test "145_ManyAdditionalLightShadowTypes" to suite UniversalGraphicsTests:

145_ManyAdditionalLightShadowTypes.png

This scene contains 4 punctual lights of various types and shadow settings. Its purpose is to detect regressions related to the indexing of punctual light shadows.
I manually checked that changing shadow type for lights in the scene, caused the test to detect a failure.

Yamato:

Automated test results are available here (no regression introduced to Universal Graphics and VFX tests):
https://yamato.prd.cds.internal.unity3d.com/jobs/902-Graphics/tree/universal%252Fpoint-light-shadows

I also manually checked that Universal Hybrid tests were passing.

Performance Tests:

Here are numbers describing the performance impact of enabling point light shadows in a benchmark scene with a high number of polygons:

Overall, the cost of adding Universal RP Point Light Shadows to the scene, is less than the cost of adding Built-In RP Point Light Shadows to the same scene.


Comments to reviewers

Other links related to this effort

…nt lights

Like with spot lights, resolution for each shadow map is computed every frame in order to fit all of them in the common shadow atlas.

Some of the current limitations:
- ShadowBias possibly needs more precise values
- FovBias possibly needs more precise values
- Unused shadow faces allocate a slot in the common shadow atlas
- Draw calls are generated even for shadow frustums that do not contain shadow casters
- Not tested: Standalone players
- Not tested: Dynamic scenes
- Not tested: Performances
- Not tested: Code path using Structured Buffers to pass shadow information to GPU (during shadow pass and lighting loop)
- Not tested: Deferred Renderer
Normal bias for point lights now behaves similarly as for spot lights
…- This makes point light shadows look closer to spot light shadows
…dow normal bias - This fixes the issue of shadows that changed when point light was rotated.

Built-In RP uses a similar approach to apply punctual light shadow normal bias. See UnityWorldSpaceLightDir called by UnityClipSpaceShadowCasterPos in UnityCG.cginc:
https://github.cds.internal.unity3d.com/unity/unity/commit/93015b67a6e1afdfe00867fdd3a336eaa835f54d#diff-c2818feb2f37e566cf36ca5cab57a99eR533
https://github.cds.internal.unity3d.com/unity/unity/blob/93015b67a6e1afdfe00867fdd3a336eaa835f54d/External/shaderlab/CGIncludes/UnityCG.cginc#L76
…s, to avoid missing shadows at cube face boundaries
…adow data to the lighting shaders + Fixed indexing issue when using non-shadow-casting additional light

Some known issues still happening:
- If only a single light in the scene is set to use soft shadows, all punctual light shadows will be soft (even if their setting is "Hard")
- Toggling setting "Soft Shadows" in UniversalRP asset also impacts shape of shadows from punctual light set to cast "Hard Shadows"
…ot light shadow's Normal Bias to match reference image - Since revision ed8fcbe Normal Bias is applied using actual spot light direction
… use per-vertex light direction when applying shadow normal bias)
…t to ScriptableRenderContext.DrawShadows - Reduces the number of shadow casters rendered to the shadow map
…nd 143_SSAO_DepthNormals_Orthographic directional light shadows Normal Bias to match reference images - Since revision ed8fcbe formula to apply Normal Bias changed slightly
…dditional light shadows

Test fails if "hard shadows" setting is replaced by "soft shadows" setting
Test fails if "soft shadows" setting is replaced by "hard shadows" setting
Test fails if "no shadows" setting is replaced by "shadows" setting
Test fails if one of the punctual lights in the scene is not rendered
@Wilfrid-Unity Wilfrid-Unity requested review from a team and martint-unity and removed request for a team and martint-unity August 17, 2020 08:00
@vaidasma vaidasma self-requested a review October 13, 2020 09:04
@vaidasma

Copy link
Copy Markdown

Tested on devices:
N/A, Xiaomi Mi A2 (Mi A2), Android 9, CPU: Snapdragon 660, GPU: Adreno (TM) 512
VLNQA00267, Samsung Galaxy S10+ (SM-G975F), Android 10, CPU: NOT FOUND, GPU: Mali-G76
VLNQA00230, Oneplus OnePlus6T (ONEPLUS A6013), Android 9, CPU: Snapdragon 845 SDM845, GPU: Adreno (TM) 630
VLNQA00010, Samsung Galaxy S8 (SM-G950U), Android 7.0, CPU: Snapdragon 835 MSM8998, GPU: Adreno (TM) 540
VLNQA00326, Samsung Galaxy Note10+ (SM-N975W), Android 10, CPU: Snapdragon 855 SM8150, GPU: Adreno (TM) 640
VLNQA00011, Xiaomi Mi 5s (MI 5s), Android 6.0.1, CPU: Snapdragon 820 MSM8996, GPU: Adreno (TM) 530
VLNQA00237 iPhone 6S A7 13.7
VLNQA00190 iPhone 5S A9 12.4.8

Tested gfx API's: Gles3, Vulkan, Metal

Project used for testing (modified to include realtime point lights with settings' variations):
https://github.com/ernestasKupciunas/Winter
https://github.cds.internal.unity3d.com/aleksandras-dzikia/mobile_realtime_lighting

Any shadow settings did not seem to produce glitches or any other visual artifacts.
Exception being one device:

Oneplus OnePlus6T - crashes when GLES3 is set as a gfx api (on Mono and IL2CPP). attaching a logcat

StackTraceGles3OnePlus6T.txt

@Wilfrid-Unity

Copy link
Copy Markdown
Contributor Author

Thanks a lot for the tests on mobiles @vaidasma

Oneplus OnePlus6T - crashes when GLES3 is set as a gfx api (on Mono and IL2CPP). attaching a logcat

Are you able to find exactly which of the commits introduces the crash on OnePlus6T GLES3?

# Conflicts:
#	TestProjects/UniversalGraphicsTest/Assets/ReferenceImages/Linear/OSXEditor/Metal/None/142_SSAO_DepthNormal_Projection.png
#	TestProjects/UniversalGraphicsTest/Assets/ReferenceImages/Linear/WindowsEditor/Direct3D11/None/142_SSAO_DepthNormal_Projection.png
#	TestProjects/UniversalGraphicsTest/Assets/ReferenceImages/Linear/WindowsPlayer/Direct3D11/None/142_SSAO_DepthNormal_Projection.png
#	TestProjects/UniversalGraphicsTest/ProjectSettings/EditorBuildSettings.asset
#	com.unity.render-pipelines.universal/CHANGELOG.md
#	com.unity.render-pipelines.universal/Documentation~/upgrade-guides.md
#	com.unity.render-pipelines.universal/ShaderLibrary/Shadows.hlsl
#	com.unity.render-pipelines.universal/Shaders/Utils/Deferred.hlsl
… active at the same time

This fixes the issue illustrated by internal ticket https://fogbugz.unity3d.com/f/cases/1290117
…n GLES3.0 devices, by reducing _AdditionalLightsWorldToShadow size
@Wilfrid-Unity

Copy link
Copy Markdown
Contributor Author

Oneplus OnePlus6T - crashes when GLES3 is set as a gfx api (on Mono and IL2CPP). attaching a logcat

Thank you very much @vaidasma for your help with remote testing on OnePlus device.
I found that the issue happened from revision 2184cd9, it looks like stripping GLES shaders causes the issue with this device,

I added work-around 5330ff9 and could run the repro project on OnePlus6T after that.

@vaidasma vaidasma left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The OnePlus6T crashing issues have been resolved.

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Last remaining issues I found have been fixed.
Test doc here

…l/point-light-shadows

# Conflicts:
#	com.unity.render-pipelines.universal/Editor/ShaderGraph/Targets/UniversalTarget.cs
…ional Lights too

Fixes "shadows popping" behavior illustrated by https://github.com/Unity-Technologies/BoatAttack/tree/testing/urp-pointlight-shadows, when changing PipelineAsset's "Shadows Max Distance" setting

@Verasl Verasl left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@Wilfrid-Unity Wilfrid-Unity added the ready-to-merge Add this tag whenever your PR is ready to be merged. i.e, non draft, all reviewers approved, ABV label Nov 30, 2020
@ellioman

Copy link
Copy Markdown
Contributor

Yamato failures not caused by this PR. Good to merge.

@ellioman ellioman merged commit a803690 into master Nov 30, 2020
@ellioman ellioman deleted the universal/point-light-shadows branch November 30, 2020 10:46
@ellioman ellioman removed the ready-to-merge Add this tag whenever your PR is ready to be merged. i.e, non draft, all reviewers approved, ABV label Nov 30, 2020
Wilfrid-Unity added a commit that referenced this pull request Dec 14, 2020
* Update Runtime/Passes/AdditionalLightsShadowCasterPass to support point lights

Like with spot lights, resolution for each shadow map is computed every frame in order to fit all of them in the common shadow atlas.

Some of the current limitations:
- ShadowBias possibly needs more precise values
- FovBias possibly needs more precise values
- Unused shadow faces allocate a slot in the common shadow atlas
- Draw calls are generated even for shadow frustums that do not contain shadow casters
- Not tested: Standalone players
- Not tested: Dynamic scenes
- Not tested: Performances
- Not tested: Code path using Structured Buffers to pass shadow information to GPU (during shadow pass and lighting loop)
- Not tested: Deferred Renderer

* Enable shadow parameters in Point Lights Inspector windows

* Add comments

* Fix point light shadow normal bias issues

Normal bias for point lights now behaves similarly as for spot lights

* Include point light shadow fov bias when computing their normal bias - This makes point light shadows look closer to spot light shadows

* For punctual lights, use per-vertex light direction when applying shadow normal bias - This fixes the issue of shadows that changed when point light was rotated.

Built-In RP uses a similar approach to apply punctual light shadow normal bias. See UnityWorldSpaceLightDir called by UnityClipSpaceShadowCasterPos in UnityCG.cginc:
https://github.cds.internal.unity3d.com/unity/unity/commit/93015b67a6e1afdfe00867fdd3a336eaa835f54d#diff-c2818feb2f37e566cf36ca5cab57a99eR533
https://github.cds.internal.unity3d.com/unity/unity/blob/93015b67a6e1afdfe00867fdd3a336eaa835f54d/External/shaderlab/CGIncludes/UnityCG.cginc#L76

* Update comments

* Fix limit of shadow map slices available when using the "Uniform Buffer" code path

* Fix in all supported resolutions point light shadow frustum fov biases, to avoid missing shadows at cube face boundaries

* Fix Point Light Shadows in Deferred Renderer

* Point Light Shadows work also when using StructuredBuffers to pass shadow data to the lighting shaders + Fixed indexing issue when using non-shadow-casting additional light

Some known issues still happening:
- If only a single light in the scene is set to use soft shadows, all punctual light shadows will be soft (even if their setting is "Hard")
- Toggling setting "Soft Shadows" in UniversalRP asset also impacts shape of shadows from punctual light set to cast "Hard Shadows"

* Fix out-of-bound array access reported by several tests in the UniversalGraphicsTest suite

* Enable per-light "soft" or "hard" shadow type setting

* Update UniversalGraphicsTest scene 105_TransparentReceiveShadows's spot light shadow's Normal Bias to match reference image - Since revision ed8fcbe Normal Bias is applied using actual spot light direction

* Apply change ed8fcbe to Terrain shaders too (i.e for punctual lights, use per-vertex light direction when applying shadow normal bias)

* Fix issue: "disabling Soft Shadows in UniversalRP.asset changes shape of Hard Shadows"

* Assign ShadowSplitData info to ShadowDrawingSettings before passing it to ScriptableRenderContext.DrawShadows - Reduces the number of shadow casters rendered to the shadow map

* Update UniversalGraphicsTest scenes 142_SSAO_DepthNormal_Projection and 143_SSAO_DepthNormals_Orthographic directional light shadows Normal Bias to match reference images - Since revision ed8fcbe formula to apply Normal Bias changed slightly

* Add an entry to changelog.md

* Update comment about Directional Light Shadow culling

See also native-side changes introduced for Persistent Intermediate Renderer:
https://github.cds.internal.unity3d.com/unity/unity/commit/89f4e3b
https://github.cds.internal.unity3d.com/unity/unity/commit/fbe6025
https://github.cds.internal.unity3d.com/unity/unity/commit/8652678

* Add Obsoletes and #defines to avoid user script/shader compilation errors

* Update comment about Directional Light Shadow culling (2)

* Add UniversalGraphicsTest suite scene checking for regressions with additional light shadows

Test fails if "hard shadows" setting is replaced by "soft shadows" setting
Test fails if "soft shadows" setting is replaced by "hard shadows" setting
Test fails if "no shadows" setting is replaced by "shadows" setting
Test fails if one of the punctual lights in the scene is not rendered

* Update reference image for UniversalGraphicsTest #145 on OSX

* Update reference image for UniversalGraphicsTest #145 on OSXEditor

* Fix issue "influence of point light shadow depth bias depends on spotlight angle" introduced in 1552692

* Re-introduce variable _LightDirection and introduce _LightPosition (instead of _ShadowCastingLightParameters from revision 6341928)

This avoids deprecation of public variables, and makes code easier to understand
Addresses comments:
#1616 (comment)
#1616 (comment)
#1616 (comment)

* Remove unused structure ShadowData from hlsl declarations

Addresses comment #1616 (comment)

* Make code slightly more readable as suggested in #1616 (comment)

* Move deprecated variable declarations, and avoid shader API breakage

Addresses following comments:
#1616 (comment)
#1616 (comment)
#1616 (comment)

* Mark ShaderInput.ShadowData as obsolete - Addresses comment #1616 (comment)

Moving ShaderInput.ShadowData declaration into com.unity.render-pipelines.universal/Runtime/Deprecated.cs would cause compilation errors (because it is in a different assembly), therefore a different Deprecated.cs file must be used (in the Unity.RenderPipelines.Universal.ShaderLibrary assembly)

* Apply change ed8fcbe to ShaderGraph shaders too (i.e for punctual lights, use per-vertex light direction when applying shadow normal bias)

Addresses comment #1616 (review)

* Add comment

* Avoid storing incorrect depth in shadow map when object scale causes vertices to be outside shadow frustum

Issue illustrated by project https://github.com/Wilfrid-Unity/scaled-box-spot-shadow

* Update UniversalGraphicsTest scenes 144_SSAO_RenderToBackBuffer directional light shadows Normal Bias to match reference images - Since revision ed8fcbe formula to apply Normal Bias changed slightly

* Add upgrade guide entry regarding Normal Bias

Formula changed in ed8fcbe

* Update documentation

* Update UniversalGraphicsTest scene 145_ManyAdditionalLightShadowTypes reference images

* Apply change ed8fcbe to ComplexLit shader too (i.e for punctual lights, use per-vertex light direction when applying shadow normal bias)

* Update UniversalGraphicsTest scene 143_SSAO_DepthNormals_Orthographic reference images

* Add documentation page about shadows

According to https://docs.google.com/document/d/1tkQdYKx2bED5hp3dTmUlkeZS_moiUsRZeMS4hMXHfXk/edit?disco=AAAAG79JQOc

* Update changelog

Addresses comment https://github.com/Unity-Technologies/Graphics/pull/1616/files?file-filters%5B%5D=.md#r488637466

* Update versioning in documentation

* Do not remove older version of ShadowUtils.ExtractDirectionalLightMatrix

Related comment: #1616 (comment)

* Update reference images for UniversalGraphicsTest 142 (SSAO)

* Strip unused ShadowCaster shader variants

* Use the same value as Built-In RP for Point-Light Shadows Normal Bias (0.0)

* Match default Additional Lights Shadow Atlas resolution to default Main Lights Shadow Atlas resolution (this also matches default point light light shadow slice resolution to Built-In RP default lowest shadow quality setting)

* Revert URP.asset files used for tests (incorrectly modified in 25f890c )

* Add explanations about Normal Bias in Editor U.I

* Update URP GFX test #145 reference images (becasue normal bias for point lights changed in 503afaf

* Use a slope-scaled depth bias (like HDRP and Built-In RP) to reduce shadow acne on self-shadowing objects

Fixes shadow acne illustrated by scene Wilfrid-Unity/compare-rp-shadows@bdd8aa2b62e48c5a2dffa5357c86792d1a864fe6( that tries to reproduce symptoms reported by @simon-engelbrecht-soerensen )

* Restore default depth bias values before exiting ShadowUtils.RenderShadowSlice

Fixes rendering issue that happened in revision 7c022e1 with test TestProjects/UniversalGraphicsTest/Assets/Scenes/119_CameraToRTWithViewportRect

* [Universal RP] Add support for custom additional (i.e punctual) light shadow resolution

Includes UI similar to HDRP, and a new Graphics test

* Enable incorrectly commented out debug warnings

* Give Yamato more time to build DX11 & Android-ES3 Graphics test projects (~30min -> ~5h)

* Prevent rendering issues when too many shadowed additional lights are active at the same time

This fixes the issue illustrated by internal ticket https://fogbugz.unity3d.com/f/cases/1290117

* Improve performance on mobiles, and avoid shader compilation issues on GLES3.0 devices, by reducing _AdditionalLightsWorldToShadow size

* Improve performance on Mobiles (especially for scenes with lot of overdraw)

Thanks again to @hkr suggestion

* Add work-around against OnePlus6T GLES3 crash reported in #1616 (comment)

Work-around can be removed after https://fogbugz.unity3d.com/f/cases/1293454/ is fixed

* Fix incomplete initialization of _AdditionalShadowParams that could cause stale data artifacts after disabling a light

Solves internal issue https://fogbugz.unity3d.com/f/cases/1293532/

* Do not render shadow slices for which we cannot allocate a big enough slot in the shadow atlas

This avoids visual artifacts happening when there are too many shadows ; as illustrated in internal ticket https://fogbugz.unity3d.com/f/cases/1289619

# Conflicts:
#	com.unity.render-pipelines.universal/Runtime/Passes/AdditionalLightsShadowCasterPass.cs

* Only output additional light shadows warnings when the shadow configuration changes

# Conflicts:
#	com.unity.render-pipelines.universal/Runtime/Passes/AdditionalLightsShadowCasterPass.cs

* Fix merge conflict

* Update UniversalGraphicsTest reference images (results from change 503afaf )

* Update UniversalGraphicsTest reference image for Android/Vulkan

* Make changelog more clear to reflect comment #2126 (comment)

* Add public APIs documentation as recommended in #2126 (comment)

* Adjust Point Light shadow resolution in UniversalGraphicsTest#105 in order to match reference images

* Apply Main Light's shadow fade (based on distance to camera) to Additional Lights too

Fixes "shadows popping" behavior illustrated by https://github.com/Unity-Technologies/BoatAttack/tree/testing/urp-pointlight-shadows, when changing PipelineAsset's "Shadows Max Distance" setting

* Update UniversalGraphicsTest reference images (iPhone)

* Fix inconsistency in code handling high number of punctual light shadows

Solves issue described in https://docs.google.com/document/d/1tkQdYKx2bED5hp3dTmUlkeZS_moiUsRZeMS4hMXHfXk/edit#bookmark=id.dqn8fqx5f45
(i.e: repro by editing TestProjects/UniversalGraphicsTest/Assets/Scenes/010_AdditionalLightsSorted/SortedLightsTestPrefab.prefab to make the meshes cast shadows, and running UniversalGraphicsTest#010_AdditionalLightsSorted)

* Fix incorrectly initialized array

Solves issue happening when after procedure described in https://docs.google.com/document/d/1tkQdYKx2bED5hp3dTmUlkeZS_moiUsRZeMS4hMXHfXk/edit#bookmark=id.dqn8fqx5f45
(i.e: repro by editing TestProjects/UniversalGraphicsTest/Assets/Scenes/010_AdditionalLightsSorted/SortedLightsTestPrefab.prefab to make the meshes cast shadows, running UniversalGraphicsTest#010_AdditionalLightsSorted, and switching to Scene view)

* Update UniversalGraphicsTest reference image (iPhone)

* Cache array member variable (to reduce heap allocations)

See example in section "Unity function calls" of https://learn.unity.com/tutorial/fixing-performance-problems

* Increase priority of shadowRequests for light near camera to reduce shadow popping when scene uses more shadows than what the atlas can hold

Mitigates issues illustrated by test scene https://github.com/Wilfrid-Unity/compare-rp-shadows/blob/master/urp-shadows/Assets/Scenes/010_ManyPointShadows.unity

* Update UniversalGraphicsTest reference image for Android-GLES3
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

9 participants