Search Unity

Question Mixed Cached Shadow Maps Advice

Discussion in 'High Definition Render Pipeline' started by Passeridae, Jul 22, 2021.

  1. Passeridae

    Passeridae

    Joined:
    Jun 16, 2019
    Posts:
    395
    Hi!

    I use Unity 2021.2 beta + HDRP 12.
    And I have an interior scene where the interior itself (walls, floors, etc) and big objects (sofas, tables, etc) are always static and therefore baked into lightmaps in the shadowmask mode. All objects that are relatively small and can be picked up (like books, boxes, small chairs, etc) are supposed to receive and cast real-time shadows from punctual lights. Lights themselves never move or change.

    But due to the new shadow caching features and the fact, that only one movable object can be picked up (in other words moved) at a time, I've been wondering if it is possible to cache the shadowmap for all these objects and refresh it only when one of them has been picked up. Preferably refresh the shadow for this object only.

    How do I do that?
    Do I set all potentially movable objects to "Static Shadow Caster", the light component to "Always Draw Dynamic" with "On Demand" update mode and every time when the object is about to move, I disable the "Static Shadow Caster" option and request the shadow atlas update via script somehow?
     
  2. francescoc_unity

    francescoc_unity

    Unity Technologies

    Joined:
    Sep 19, 2018
    Posts:
    193
    Not sure I understand 100%, but if you want to update only when a specific object is moved, you can ignore the Always Draw Dynamic feature, you can instead have it to OnDemand with the Always Draw Dynamic set to off, and trigger the update via script (as mentioned in the documentation: https://docs.unity3d.com/Packages/c...h-definition@12.0/manual/Shadows-in-HDRP.html ) whenever your condition is matched (i.e. your relevant object has moved).

    The static shadow caster flag is only used to determine what will need to render every frame if Always Draw Dynamic is set to true; it is otherwise ignored, so no need to unset it.

    Please let me know if I misunderstood what you are trying to do.
     
  3. Passeridae

    Passeridae

    Joined:
    Jun 16, 2019
    Posts:
    395
    Thanks for your reply!
    I'll try to re-explain a bit clearer. Say, I have a scene with 10 cubes. Each one of them can potentially be moved. Hence, I use real-time shadows. But only one of them can be moved at a time. It's also possible that none will be moved for a long time. So, I want to save performance and do not update real-time shadows each frame for not moving cubes.

    So,
    1) How do I ensure that when one of them is moved, the shadow it casts starts to update accordingly?
    2) Is it possible to update only the shadow cast by this particular cube, leaving the shadows from other 9 cubes still cached?

    The docs say that "It is possible to cache only a portion of the shadow map. To do this, enable the Always draw dynamic option...". So I thought that if I want the shadows from 9 not-moving cubes stay cached and the shadow from the 1 moving cube be updated, I have to use this option, or all shadows even for not-moving objects will be updated when a single cube is moved. But it seems I got it wrong?

    Thanks!
     
  4. francescoc_unity

    francescoc_unity

    Unity Technologies

    Joined:
    Sep 19, 2018
    Posts:
    193
    Oh I do get your point better now, then yes, what you proposed originally sounds like the right way to go.

    - Keep the "Always draw dynamic" option on always, doesn't matter if OnDemand or OnEnable in this case.
    - From script toggle the object that is moved so that it is not static shadow caster anymore when you detect from your end a movement.
    - When said movement is finished (or you determine OK not to update shadows anymore) you can switch back the flag "static shadow caster"

    This will keep everything cached as everything is "static shadow caster" until something move and you deselect such option, leading to said object ending up in the dynamic queue and being rendered.

    Having the option Always draw dynamic does indeed force the dynamic to be rendered at each frame as we cannot unfortunately do motion tracking for all objects from HDRP side. However, as I mentioned above, if you can do said detection on your end you can determine constantly what's dynamic or not.
     
  5. Passeridae

    Passeridae

    Joined:
    Jun 16, 2019
    Posts:
    395
    Thanks! However, in this case, I have an additional question:

    - I created a cube and set it to "static shadow caster"
    - I created a spotlight and set it to "always draw dynamic"

    Now, if I move the cube, its shadow stays in place. That's expected, it confirms that It's cached. Okay, I return the cube to the initial position, then I disable "static shadow caster" and move it again:
    upload_2021-7-22_20-0-22.png

    So, it seems that the cached shadow still stays in place and another one is created and updated in real time.
    Now, I enable the "static shadow caster" option again, and the real-time shadow disappears:
    upload_2021-7-22_20-2-16.png

    But when I disable and then enable the light again or change the shadowmap resolution. the wrong shadow is discarded and the right one appears. So, I suspect the full algorithm is supposed to look like this:

    - Keep "Always draw dynamic" and "static shadow caster" always enabled by default.
    - When movement is detected, disable "static shadow caster" on the movable object and call the "RequestShadowMapRendering" to update the shadow map and discard the cashed shadow, to avoid shadow duplication.
    - When movement is finished, enable "static shadow caster" and call "RequestShadowMapRendering" again, to cache the shadow for the object.

    Am I right?
     
    Last edited: Jul 22, 2021
  6. francescoc_unity

    francescoc_unity

    Unity Technologies

    Joined:
    Sep 19, 2018
    Posts:
    193
    Yes, you are right, that sounds about right.
     
    Passeridae likes this.