Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. Dismiss Notice

Shadow performance and quality -- will it be improved? Will we ever get better soft shadows?

Discussion in 'Universal Render Pipeline' started by PutridEx, Jun 23, 2021.

  1. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    Pretty sure Unity can't use any of these unless you make PRs to their Graphics repo with these changes :)
     
    tatoforever likes this.
  2. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    This is trivial to achieve in URP, but you'd have to use unlit and roll your own lighting, or make use of emission output. It definitely is doable but cumbersome.
     
    burningmime likes this.
  3. burningmime

    burningmime

    Joined:
    Jan 25, 2014
    Posts:
    845
    Fair enough; I didn't look hard enough at it; looks like MadWorld is basically just using unlit for everything. Bit trickier with cel-shaded games that need to take lighting info from the actual lights (realtime, probes, baked, etc) and do something with it other than PBR, although given the number of cel shading shader graphs on the asset store, certainly not an unsolvable problem.
     
  4. sabojako

    sabojako

    Joined:
    Jul 7, 2017
    Posts:
    48
    Hi @nigeljw_unity,

    I just tested conservativeEnclosingSphere and numIterationsEnclosingSphere in 2021.2.15f1. There are worrysome things that I noticed while enabling the setting and tweaking the values, both from numIterationsEnclosingSphere and cascade Splits:
    • The shadow drawcall count skyrockets between +30% and +200%, depending on FOV, far plane, shadow distance, cascade count and cascade splits. This can be a huge performance regression for CPU.
    • It also seems like a lot of texel density (shadow quality) is lost from enabling conservativeEnclosingSphere. You can clearly see this when looking at the shadowmap in the frame debugger. If a game uses only 1 shadow cascade, there is no possibility to tweak the cascade splits, so no possibility to get back that lost texel density after enabling conservativeEnclosingSphere. This also seems like a big visual quality regression.
    • Those problems are very apparent on a perspective camera. Orthographic camera seems little to not affected by conservativeEnclosingSphere.
    I'd like you guys to highlight those potential problems if those don't get fixed. And keep the conservativeEnclosingSphere toggle exposed. I'm not even sure if conservativeEnclosingSphere should be enabled by default honestly, as shadows can be a huge bottleneck.

    On the matter of directional shadowmap texel density, I've always struggled with understanding how the orthographic size of the shadow projection is generated. I've noticed that a lot of the times it seems the projection is too large, like a lot of texture space is wasted. And as I said above, this is very problematic with conservativeEnclosingSphere. Is there a way you could expose the size of the shadow projections to users?

    In BiRP, there was a setting ShadowProjection.CloseFit which reeeally tightened the projection and texel density. Are there any plans to bring CloseFit back? If not, is there a way that we can reproduce its result?

    About ScriptableCullingParameters.shadowNearPlaneOffset: I am grateful for this addition. Sounds like less fighting with the SetShadowCullingPlane API. I noticed that pushing a negative value will reduce shadow drawcalls and result in better texel density, which is good. On the contrary, pushing a positive value results in lower texel density, BUT also reduces shadow drawcalls, which doesn't sound expected. Why does it reduce drawcalls?

    For the record, there is also a "shadowNearPlaneOffset" setting in QualitySettings when using BIRP, which does something completely different and does not influence culling. Could be good to clarify this up.

    Cheers!
     
    Last edited: Mar 29, 2022
    NotaNaN, PutridEx and joshcamas like this.
  5. PutridEx

    PutridEx

    Joined:
    Feb 3, 2021
    Posts:
    1,120
    @nigeljw_unity
    Any ideas on what might be coming to URP in regards to shadows for 2022.2?
    Any noticeable new features/improvements?
     
  6. nigeljw_unity

    nigeljw_unity

    Unity Technologies

    Joined:
    Oct 7, 2020
    Posts:
    50
    Thanks so much for testing this out! You need to re-author your cascades relative to your scene after enabling or disbaling conservativeEnclosingSphere, as this changes the size and position of cascades. It can't be compared by just toggling the setting. This is the main reason why it is currently disabled by default. If you use the new renderering debugger feature to visualize your cascades, this can help in re-authoring your cascades significantly. "Window => Analysis => Rendering Debugger => Lighting => Lighting Debug Mode => Shadow Cascades". Unfortunately, currently, this shows the rendering for the scene view camera instead of pinning game view, so you need to make sure you view this visualization in game view mode when configuring your cascades.



    We generally see an average static caster reduction of about 30% in our internal tests. For some scenes, there will be an increase in static caster count, but that is because those casters were previously erroneusly culled relative to the configured frustum far plan and shadow distance, so you need to adjust your camera and cascade configuration appropriately.

    The new setting is specific to cameras as specified in the new docs, whereas the old setting is specific to lights. I'll submit an issue to the docs team to get this clarifeid. It is the same functionality, except the difference is between light and camera frustums (the other setting will affect culling for light frustums). In the SRPs, the light's shadowNearPlaneOffset setting is on the light component itself "Light inspector => Realtime Shadows => Near Plane":
    https://docs.unity3d.com/Packages/c...es.universal@13.1/manual/light-component.html

    There are some brief details about how to use the light's shadow near plane offset in this document:
    https://docs.unity3d.com/2022.2/Documentation/Manual/ShadowPerformance.html
     
  7. Neto_Kokku

    Neto_Kokku

    Joined:
    Feb 15, 2018
    Posts:
    1,751
    Shadow culling in Unity has always been lackluster, and URP inherited most of that. Here are two common and relatively simple techniques Unity could use which can drastically reduce the number of rendered shadow casters:
    • Exclusive cascade culling: if an object bounding volume is completely inside a cascade, exclude it from the next cascades.
    • Extruded frustum shadow culling: to cull shadows which would fall outside the camera frustum, create a convex by extruding the frustum volume in the inverse light direction and cull casters which don't overlap it. The extruded convex has at most 12 planes compared to a frustum 6 planes.
     
    tspk91 and sabojako like this.
  8. PutridEx

    PutridEx

    Joined:
    Feb 3, 2021
    Posts:
    1,120
    Will URP get capsule shadows in 2022.2, it's coming for HDRP.
    Curious since I saw the author experimenting with URP for a bit as well.
     
  9. LaireonGames

    LaireonGames

    Joined:
    Nov 16, 2013
    Posts:
    696
  10. rz_0lento

    rz_0lento

    Joined:
    Oct 8, 2013
    Posts:
    2,361
    From 2022.2.0a9 release notes:
     
  11. PutridEx

    PutridEx

    Joined:
    Feb 3, 2021
    Posts:
    1,120
    Nice!
    Although I heard from the next-gen shadows author that this is as good as it's gonna get, Tent 7x7. They don't plan for anything better after that. This was a week or two ago.
     
  12. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    Thanks for the much needed explanation, it helps a ton.
     
    nigeljw_unity likes this.
  13. PutridEx

    PutridEx

    Joined:
    Feb 3, 2021
    Posts:
    1,120
    "Medium 5x5 soft shadows": (previous default)
    upload_2022-4-1_19-29-28.png

    "High 7x7 soft shadows": (only 2022.2)
    upload_2022-4-1_19-29-59.png


    next-gen shadows:
    Unity_nOzxjd1WXI.png

    next-gen lower smoothness value & higher res (pretty low on previous screenshot):

    I have to say, 7x7 is better than 5x5 so no complaints from me. Great stuff :D
    But, next-gen is on a whole new level, and completely adjustable including smoothness value.. a bit disheartening
    It almost feels raytraced.
     
    Last edited: Apr 1, 2022
  14. tatoforever

    tatoforever

    Joined:
    Apr 16, 2009
    Posts:
    4,337
    @PutridEx,
    Side NGSS note, using a PCF with min softness at min and max at max would provide pseudo raytraced like shadows where shadows are harder at close distance between caster/receiver and softer if caster/receiver distance is large.
    The reason why Unity opted for a fixed kernel is because is more predictable for drivers to optimize and tend to miss cache less than variable kernel size algorithms such as the ones in NGSS. However this is now less true as even mobile drivers start to get a lot better at optimization and cache miss.
     
    rz_0lento and PutridEx like this.
  15. Khang_Pham

    Khang_Pham

    Joined:
    Feb 28, 2021
    Posts:
    13
    Hi @nigeljw_unity

    may I ask if there is any ETA on the shadow caching for URP yet? Is this still planned?

    "Cached static shadows is very high in priority on our raster shadow roadmap. The only thing we actually have as a higher priority at the moment is moving the shadow depth bias from the caster to the receiver"

    This was almost one year ago but I can not find any info regarding this anywhere. With no mention of this feature in the official Unity URP Roadmap.

    Even a very rough ETA would be immensely helpful.
    Especially considering that Unreal implemented Shadow Caching more than 4 years ago (see Fortnite mobile)...
    This is somewhat discouraging for every Unity Developer...
     
  16. Kinami37

    Kinami37

    Joined:
    Jun 12, 2016
    Posts:
    13
    Where do you find the options for the 5x5 and 7x7? Using 2022.2 a11 rn and its nowhere to be seen for me
     
  17. PutridEx

    PutridEx

    Joined:
    Feb 3, 2021
    Posts:
    1,120
    I believe it's configurable per light, I did my test with the directional light.
    Click on the directional light and in the inspector, the option should be somewhere around the shadow settings.
     
  18. Kinami37

    Kinami37

    Joined:
    Jun 12, 2016
    Posts:
    13
    Ah I see yeah.

    I tried to compare it to 2021 LETS but the shadow quality is still the same no matter what, i wish NGSS would support URP already, unitys default shadows are just so bad
     
  19. Neto_Kokku

    Neto_Kokku

    Joined:
    Feb 15, 2018
    Posts:
    1,751
    The extensibility NGSS uses to work on built-in doesn't exist in URP. The only viable way, AFAIK, would be to make a fork of URP since those changes would need to go directly into its source code.
     
  20. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    950
    @nigeljw_unity it is not as simple as re-authoring cascades to fix everything. Metric working unit is plain wrong when conservative enclosing sphere is enabled. (Last Border is also wrong in all cases, it controls 0-100% Max Distance fade range no matter what the inspector and documentation says).

    Unity 2021 LTS URP 12.1.7
    Cascade splits 40, 60, 100, max 150 Metric without conservative, fairly accurate and goes a bit beyond max distance:

    without-cascades.png

    And with conservative, same settings, doesn't match metric at all and goes way beyond max distance, note that the last cascade is not visible at all:
    with-cascades.png

    Shadow map without conservative:

    without-shadows.png

    Shadow map with conservative:

    with-shadows.png

    With conservative mode the metric working unit is plain wrong. Percent works, but you have no idea how far the shadows extend because they go way beyond the max distance, rendering useless shadows. Re-authoring cannot avoid rendering many unneeded shadows here.

    I rather use the old approach, plus improved shadow fading that also takes the outer cascade sphere into account.
     
    sabojako and r9shackleford like this.
  21. nigeljw_unity

    nigeljw_unity

    Unity Technologies

    Joined:
    Oct 7, 2020
    Posts:
    50
    The diameter of the cascade sphere is not the distance from the centroid of the cascade to the far plane of the cascade. The sphere has to enclose the cascade, so that the shadow map is entirely enclosed. Every corner of the cascade ideally lays on the surface of the shere, with the corners always conservatively within the sphere, so it will be very slightly larger, unless you increase numIterationsEnclosingSphere for the method to be more accurate and closer to the real solution, though it is unlikely that it would need more than the default of 64 iterations. Non-square aspect ratios for the sides of the cascades will potentially make the spheres larger relative to the depth of the cascade.

    upload_2022-10-28_22-26-14.png

    In your second image, the last cascade is visibile in the top left and right corners. In your first image, the first cascade does not cover any geometry. Or do you have objects closer to the camera in the final rendering for gameplay? If not, then the shadowNearPlaneOffset for the camera can potentially help.

    Can you share your project through the bug submission tool in the editor in regards to the trouble you are having specifically with respect to the conservative enclosing sphere? I'll do a first pass on re-authoring the cascades and configuring the shadow settings. It might need a higher default for numIterationsEnclosingSphere, but that is relatively unlikely.

    With regards to the issues with shadow fade, last border, and shadow distance, I have previously reported these issues to the URP team. I will follow up with them again on that problem specifically.
     
    wwWwwwW1 and r9shackleford like this.
  22. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    950
    @nigeljw_unity Thank you for your reply!

    It would be so great if this was actually documented! Whatever the non-conservative mode does is way more intuitive as it better matches the suggested distances and seems to have a sensible relationship with the max distance.

    The last cascade is practically useless because it is not visible as it lies beyond the max shadow distance. Note where the shadows get cut off, about halfway the yellow band in the second image. Thus it is a performance problem because way too many shadows casters get rendered. The max distance has become an arbitrary cut-off line for showing shadows, but they still get rendered way beyond that distance.

    Neither in the second image. First is missing cascades 0 and 1, while second is missing cascade 0. This is because those cascades are used for close-ups while the current view is high-altitude. In the actual project I only use two cascades, which have the same problem as shown here - most of the last cascade is wasted - it's just more visually obvious with four cascades.

    Yes: IN-21329 - URP incorrect shadow cascades and fading. In there I also show the max shadow distance on the terrain to make it easy to notice how much shadows get rendered for nothing.

    I suggest eliminating the Metric mode entirely because it is plain wrong.
     
    LooperVFX likes this.
  23. nigeljw_unity

    nigeljw_unity

    Unity Technologies

    Joined:
    Oct 7, 2020
    Posts:
    50
    @Jasper-Flick Thanks for the feedback, it is invaluable!

    So the reason why we define enclosing culling spheres is because we need to make the shadow maps invariant to view transformations, otherwise it causes severe perspective alaising that is non deterministic between frames, so it causes severe shadow shimmering, which you probably already know. The metric dimensions specify the cascade sizes for the frustum, and not the spheres. I definitely agree that we should improve the documention on this, and also probably provide the below details, since this is such a complicated feature.

    The enclsoing culling spheres define the world space that the shadow map covers, so the spheres need to fully enclose the cascade, ortherwise there are regions wihtin the cascade that will not be covered by the shadow map. We also use these spheres to cull shadow casters, so if these spheres do not fully enclose the cascades, there will be false positives, that will cause visible popping and missing shadows. The following images are using the new enclosing spheres, with a simplification to 2D so that the enclosure is actually perceptable, as in 3D, it needs a properly shaded sphere.

    upload_2022-11-1_21-37-12.png





    Currently, with the legacy/default method, for cascades that are rectangular cuboids and not perfet cubes, the spheres do not properly cover the cascades. If the viewport resolution is square, or the depth of the cascade is close in size to either the width or height of the viewport. The legacy system used the determinant method of finding a sphere from 4 points, but this is wrong, since that has the requirement of the points being on the surface of the sphere, which causes the sphere to grow exponentially in size especially for oblong cascades, which are much more common especially with ultra wide screen displays, and also with dynamic cascade resizing like with custom SDSM shadows. The legacy system does try to scale the sphere down to the far plane of each cascade, but this casues the non-conversatism. The shadow fade in URP actually casues the exact same issue because it aligns to the far plane to an arc for the fade. This new enclosing sphere fixes some of the problems with the shadow fade in URP, as mentioned above, but not all of them. The legacy system actually has significantly more redundent overlap of cascades with a lot of wasted shadow map space when the cascades are properly authored with the new conervative enclosing sphere. It is significantly worse with the legacy enclosing spheres, but it is just that this overlapping space is predominantly in front of the cascade, so it is hard to understand when using the renderer debugger to visualize the cascades. The renderer debugger renders cascade layers in sorted increasing order relative to the cascade index. This technically is actually correct since the legacy ComputeVisibleSplitMask does try to check for full enclosure in a previous cascade before testing culling into the proceding shadow maps. There is a severe bug in ComputeVisibleSplitMask so the culled static castor count is not consistent due to false negatives, which are innoculous to rendering but not performance. This issue with the fully enclosed check may be fixed when generalizing the frustum culling in Graphics Entities to support game objects, though if we do choose to add the fully enclosed in a previous cascade check, then this causes us not using a job for each cascade. Currently the legacy culling does not parallize the cascade culling tests across cascades.

    upload_2022-11-1_21-36-9.png



    During the design for the conservative enclosing spheres, I proposed to have an explicit controlable per casade scale factor and offset to customize the size and positions of the spheres, but the internal feedback was that this would be too complicated of a workflow. In my opinion, it would be better if the false positives with the legacy system are an intentional action by the developer and non-default behaviour as otherwise the missing shadows can be incredible confusing to Unity developers. I would really appreciate any external feedback on this proposal as a further improvement to the new conservative enclosing sphere method. The oversizing in the legacy approach is much worse, and for etremely oblong cascades it can even cause divide by zeroes due to the determinant appoach. The scaling to the far plane should be an explicit control by the developer which defaults to fully enclosed. You already have explict control of cascade sizes and positions. Ideally, we should output the sizes and positions of the spheres so it can be used to help author the cascades when using metric dimensions. Using the renderer debugger does aready work quite well to author the cascades, but I really wish that it could be pinned to game camera in scene view, which would give you a much better understanding of the problem I have described here (we do already support pinned frustums in the debug view for our new Burst Occlusion Culling). With proper authoring we saw an average 30 percent reduction in static castor count. It your above images, you are actively choosing the cascades to be positioned in those ways. I completely agree that this is not intuitive.
     
    Last edited: Nov 1, 2022
    NotaNaN and cxode like this.
  24. Jasper-Flick

    Jasper-Flick

    Joined:
    Jan 17, 2011
    Posts:
    950
    @nigeljw_unity Thanks for the explanation!

    Now that I better know how it works the results and differences make sense. Although I'm still fuzzy about the exact definition of the cascade splits. What kind of frustum size? Without feedback to visualize it it's a fairly arbitrary value. Likewise with percentage. It gets tuned visually without any idea what the numbers actually represent.

    Currently conservative doesn't get better for ultra wide displays either. Here using two cascades (debug view cannot deal with a single cascade; it also bugs out if everything is beyond max distance by the way).

    Nonconservative:
    non-con.png

    Conservative:
    con.png

    Nonconservative shadow map:
    non-con-sm.png

    Conservative shadow map:
    con-sm.png

    I'd actually be interested in the old approach taken to the extreme: place cascades based on Max Distance only, don't demand the entire frustum be filled, so the squiggly filled missed regions in your second diagram are fine. Then fade shadows based on the cascade sphere, just like fading between cascades.

    In my case this makes sense because there is usually nothing behind the camera, so overlapping culling spheres don't lead to many useless shadow casters being rendered.

    Basically it's the current max distance fade that makes the conservative approach silly. Including that line in your first diagram - if I understand it correctly - shows the problem with the last cascade:

    with-max-distance.png
    (Not sure about the placement of the distance sphere, but it illustrates the problem nonetheless.)

    This suggests to toss the current distance-based fade and instead fade based on the cascade sphere and suddenly many more of the rendered shadows become useful. Then max distance can be tuned to an acceptable level (in the diagram it got basically doubled). But then the old approach makes more sense again, as I described in the previous paragraph, or something that combines the best of both.

    Another potential issue I see with the conservative approach is that if cascade blending regions are too large - if smaller cascades aren't perfectly contained by larger ones - holes might appear near the edge of the frustum.
     
    Last edited: Nov 2, 2022
    LooperVFX likes this.
  25. tspk91

    tspk91

    Joined:
    Nov 19, 2014
    Posts:
    130
    What about adding a configurable minimum renderer-bounds-to-cascade-size ratio to cull casters? It would be nice to remove small props from the larger cascades. It makes no sense that hundreds of props that won't even be a pixel wide to be rendered to the shadowmap.

    Another really nice thing would be to have a fully configurable cascade count. Huge for space games: Elite Dangerous uses 6 cascades, allowing for real time shadows across huge asteroid fields AND your own ship, which would be unworkable with just 4 cascades.
     
    sabojako likes this.
  26. PolyMad

    PolyMad

    Joined:
    Mar 19, 2009
    Posts:
    2,328
    This has probably already been proposed, but who knows: what about rendering the shadows at half resolution? And then apply a median filter to reduce the blocky look.
    Would it give a good boost or not so much?