Search Unity

  1. Calling all beginners! Join the FPS Beginners Mods Challenge until December 13.
    Dismiss Notice
  2. It's Cyber Week at the Asset Store!
    Dismiss Notice

Sharp Shadows Toolkit (LWRP/URP)

Discussion in 'Assets and Asset Store' started by gustavolsson, Sep 4, 2019.

  1. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    Hi everyone, I just released the Sharp Shadows Toolkit for the Lightweight Rendering Pipeline on the Unity Asset Store (link)!

    Many games target a non-photo-realistic art style and, in my opinion, the built-in shadows do not really do these games justice, especially on low quality settings. This toolkit provides an alternative shadowing solution that works out-of-the-box with the LWRP/URP.

    Website & Readme

    Feel free to use this thread to discuss the toolkit and post any questions or comments.







    For those of you that were using Unity back in the day, you might see some resemblance to an old deprecated toolkit called Shadow Volumes Toolkit, and you're right, this is the spiritual successor to my old toolkit.
     
    Last edited: Sep 20, 2019
    mkracik and Lars-Steenhoff like this.
  2. Lars-Steenhoff

    Lars-Steenhoff

    Joined:
    Aug 7, 2007
    Posts:
    2,274
    Looks very nice!
     
    gustavolsson likes this.
  3. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    Thank you! :)
     
  4. SteveB

    SteveB

    Joined:
    Jan 17, 2009
    Posts:
    1,448
    Welcome back! As before this looks fantastic :D
     
    gustavolsson likes this.
  5. God-at-play

    God-at-play

    Joined:
    Nov 3, 2006
    Posts:
    311
    It's unclear from your post and website since it's mentioned as a feature but not limitation, does this require LWRP? Because the LWRP can mess up a number of other features and packages, especially pre-2019.3. Is it possible to make some edits to not require that? If so, can you provide some guidance?

    Also yaaay!! I'm a fan of your original package, having used it like 7 years ago. I still think about it sometimes, and have considered using it a couple times the last few years, but it just didn't seem like a good idea. I'm excited you're back with an update, no hesitation needed now (LWRP notwithstanding). :)
     
    gustavolsson likes this.
  6. God-at-play

    God-at-play

    Joined:
    Nov 3, 2006
    Posts:
    311
    Oh, shoot, I missed the requirements on the right column on your personal website. Can you make sure to call that out in the Limitations? Especially for the Asset Store, that's important to know.
     
  7. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    Thanks! Great to hear :)

    Yes, LWRP is a requirement as it simplifies the rendering part quite a lot. It already says "The Sharp Shadows Toolkit brings sharp, pixel-perfect shadows to your Lightweight Render Pipeline project." on the Asset Store but I'll make sure to add it to Limitations as well!
     
  8. God-at-play

    God-at-play

    Joined:
    Nov 3, 2006
    Posts:
    311
    Thanks, yeah I appreciate that. Sometimes things are promoted as having a focus but have more broad support, I wasn't sure if that was the case here. Good to know.

    Have you started migrating this to URP? I'm curious how much work that takes.
     
  9. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    I haven't looked at it yet but I think it should be straightforward. From the looks of it on GitHub, it seems to be mainly renaming of namespaces etc
     
  10. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    Regarding the LWRP requirement, I specified that when uploading the package (there is sort of like a questionnaire), so I suspect Unity tells you about this requirement before you're actually allowed to buy it, but I'm not sure.
     
  11. magnussen81

    magnussen81

    Joined:
    Mar 8, 2019
    Posts:
    5
    Hi Gustav

    This looks interesting. Two questions:
    1. Are the shadows able to dynamically batch?
    2. Do you have any performance stats?
     
  12. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    Hi and thank you for the interest in the toolkit :)

    They're batched using the new SRP batcher if the feature is enabled. In that case there are very few draw calls when looking in the frame debugger. Here are the numbers for the example scene:

    * When shadows are injected into the screen space shadow texture: 4 for rendering depth pre-pass, 1 for rendering shadow volumes and 4 for opaques renderers
    * When shadows are rendered after opaques (color is multiplied only): 1 for rendering shadow volumes, 4 for opaques renderers

    However, I've encountered problems with the SRP batcher (it's still experimental after all) on one particular Android device so I don't think one can rely on it for production just yet, at least not for mobile.

    The performance depends heavily on the scene complexity so it's difficult to give any concrete numbers. If there's interest I can create a demo executable where one can switch between the built-in shadows and the sharp shadows so that one can measure on a target computer.

    I would say that it is quite lightweight, the technique used is shadow volumes and they are proven to work well, mostly in older games (Doom 3, the original Star Wars Battlefront etc). The performance naturally depends on the scene but everything that I've tested runs well on my MacBook Pro from 2010 with a Geforce 320M graphics card. I don't notice any performance impact on my desktop with a Geforce GTX 970.

    Mobile is a bit different and one should be careful to not put shadows on everything for those games. The shadow volumes technique is quite fillrate intensive so a weak GPU coupled with a high resolution screen is the worst case scenario. In those cases one can lower the resolution or only use shadows for selected objects (ie. the character). New phones should handle shadows well and I suspect modern iPhones etc can have shadows on all objects in native resolution, but I'm yet to test this.
     
  13. magnussen81

    magnussen81

    Joined:
    Mar 8, 2019
    Posts:
    5
    Oh, thank you very much for the quick response. I forgot to mention that I'm targeting mobiles/tablets and we're not able to use SRP Batcher (yet) since we're forced to use an older version of LWRP - in our roadmap we're targeting 2019.2 whenever AR Foundation is more production ready/stable.

    I think it would help a lot of people to decide if you gave some rough examples of performance (if it's on par or better) - it's quite obvious that the quality is better but since we're in LWRP space then latency is equally important.
     
  14. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    A general update: I've confirmed that the toolkit works well with the Universal Render Pipeline (Unity 2019.3.0b2 and URP 7.0.1) if one changes all the namespaces in C# to "Univeral" instead of "LWRP" and the namespaces in the shaders from "lightweight" to "universal".

    I just submitted an update to the toolkit that makes this switch automatically, but feel free to try for yourselves (if you're daring) while we wait for it to be accepted :)
     
  15. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    Then there will be one extra draw call per shadow being rendered (and one extra depth-pass draw call if "inject" is used instead of "multiply").

    I'll have to look into it. For mobile it doesn't really make sense to publish an app though, how do people usually do this?
     
  16. magnussen81

    magnussen81

    Joined:
    Mar 8, 2019
    Posts:
    5
    Don't think you need to publish an app - just a scene that resembles mobile more than PC. The Viking village scene you have would be okay for comparison purposes I think. but maybe the Pirate Ship one is better since there's more object and the difference would be more obvious (in terms of numbers/latency.
     
  17. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    Ok I'll see what I come up with. I think I'll manage to do it before the end of the week, stay tuned :)
     
  18. PartyBoat

    PartyBoat

    Joined:
    Oct 21, 2012
    Posts:
    82
    Hey @gustavolsson I've actually used your original Shadow Volume asset and was wishing it'd get ported to the LWRP so the timing on this is impeccable! I was wondering a couple things:
    1. In the original asset there is a problem with shadows disappearing when you enter their shadow volume. Is this still an issue?
    2. Would you consider adding support for baked shadows similar to what is found in this asset? When I tested that asset against the original version of this one the performance of the baked shadows was noticeably better for the low end devices I was targeting. Ideally I'd like to be able to mix baked and movable shadow volumes similar to the mixed mode you have with Unity's baked and real time lights. I hacked something together by combining that asset I linked and your original for a mix of baked and real time and the performance was great, but when the real-time shadows layered over the baked shadows they blended poorly. My frankensteined test scene makes me think this is feasible with a shader that can handle the blending between the two types. Why do this at all you ask? Well it's basically the only way to allow users to bake their own shadows in an in-game level editor with acceptably short bake times.
     
  19. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    Hehe :)

    No it's not a problem. You have to enable "Allow Camera In Shadow" on the generated shadow asset for objects that you know will cast shadows over the camera. The shadows of those objects will have to be rendered twice, which is why it's an option.

    I didn't plan to add it, but now that you mention it I see how it could be a nice useful feature! The vertex count for baked sharp shadows would be noticeably lower and the shader used to render them could be as simple as it gets. I'll have to think about the best way to add this feature to the new workflow though, it needs to be super-simple. (The workflow of this new toolkit is much improved over the old one!)

    I'll see if I have some more time once I complete my current project :)
     
  20. PartyBoat

    PartyBoat

    Joined:
    Oct 21, 2012
    Posts:
    82
    Sounds great, thanks for the info!
     
  21. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    I've now finished a simple demo scene for the toolkit. Click here for the WebGL version and here for the standalone Windows version (cc @magnussen81)

    While making this scene I realized that the performance is a bit worse than I thought. The builtin shadows are always faster (but look more pixelated of course). I think this is basically the nature of shadow volumes vs shadow mapping (and maybe today's graphics cards being optimized for the latter) and the higher vertex count necessary for the sharp shadows.

    It'll be interesting to see how the performance compares if I implement the shadow baking that @PartyBoat suggested. This will make the complexity of the meshes used for sharp shadows on par with the meshes used for shadow mapping.

    Even though the performance is generally worse than when using the builtin shadows, I still do believe there is a niche for the toolkit for games targeting non-photo-realistic art styles.
     
  22. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    109
    I asked in the wrong thread, apparently, but nice to see this working in WebGL, even though it seems to come with a significant performance hit of -15fps compared with shadow maps when testing it on my laptop... ;_;

    Are you using DrawMesh or DrawMeshInstanced?
     
    gustavolsson likes this.
  23. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    I'm currently using DrawMesh because I thought instancing was superseded by the SRP batcher when using a scriptable render pipeline. The frame debugger shows only one draw call for all shadows when the SRP batcher is turned on. I realize now that might have been too quick of an assumption though. I'll look into this further, thanks for bringing it up!
     
  24. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    109
    With the newer versions of Unity, Graphics. has many new ways of rendering that could perhaps be beneficial for this, but they need to be shader target limited for specific platforms like WebGL:

    https://docs.unity3d.com/ScriptReference/Graphics.html

    [Edit] Also I am really curious to see how this will be with DrawMeshInstanced() or similar GPU-based rendering. I have used your previous toolkit in the past for personal projects, but if this can have batching based on proximity/distance and GPU-rendering with materialpropertyblocking, I will definitely give it a buy. :3
     
  25. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    Yea, I'll think about ways to improve it in the future. The most notable performance improvement will be the baked shadows for static game objects. A problem is that instancing only helps if there are a lot of the same meshes in a scene, which is not the case for the demo scene. I *believe* the demo scene is GPU fill rate bound, not CPU bound, so instancing would not improve it I think. I'll investigate further!
     
    Nyanpas likes this.
  26. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    109
    In my scenario I have a large map with lots of similar objects with various materialpropertyblock-variations, and some skinnedmeshes baked to regular meshes. GPU-instancing will help a lot for this as I reuse as much as possible with variations.
     
    gustavolsson likes this.
  27. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    I did a quick test scene and made sure to enable instancing on the shadow materials (the shaders are already written for it), disabled the SRP batcher and indeed, Graphics.DrawMesh() automatically submits things to be instanced:



    I'll make a new demo scene build and see if there is any difference (as I said, I think the demo scene is GPU bound and not CPU bound unfortunately.. but we'll see)

    I'll add this small code fix (material.enableInstancing = true) to the latest update. There were some error in the asset store submission system so the latest update did not release properly and I have to resubmit :)/), but I'll make sure to add this before I do :)
     
  28. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    109
    So would it be easy for me to modify the code to use DrawMeshInstanced() instead of DrawMesh? I really want to do that instead of having to think about SRP.
     
  29. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    DrawMeshInstanced() was not needed, Unity bundles together the DrawMesh() calls automatically. The only thing that was needed was to set enableInstancing = true on the materials created in the SharpShadow.cs file.
     
  30. gustavolsson

    gustavolsson

    Joined:
    Jan 14, 2011
    Posts:
    315
    Version 1.02 is now out on the asset store! (wow that was fast)

    This version adds Universal Render Pipeline support and the instancing fix mentioned above (cc @Nyanpas). Here is the complete changelog:
     
  31. Nyanpas

    Nyanpas

    Joined:
    Dec 29, 2016
    Posts:
    109
    Very nice. :3c
     
    gustavolsson likes this.