Search Unity

HDRP - No shadows from distant point lights

Discussion in 'General Discussion' started by U2-84, Jun 5, 2020.

  1. U2-84

    U2-84

    Joined:
    Oct 25, 2012
    Posts:
    5
    Hello,
    I've been trying for hours but it seems I can't get shadows from a distant point light.
    In detail, the point light is a "star". I can't use directional light because the solar system is fully explorable, I need to be able to get from a planet to another planet or get close to the star itself.

    I increased shadow quality, resolution, played with cascades. Nothing. When I'm "close" to the point light, shadows become visible, but at certain distances they disappear (but the light keeps lighting objects so I don't think it's a "range" problem).

    I've also been thinking to "fake" the star, disabling shadowing on the point light and using a directional light always "lined up" with the point light (in this way, it seems that light comes from the point light), but it doesn't work well at short distances.

    So, in the end, I need to find a way to actively use the point light as a fully functional light with shadows enabled and visible.

    Any help?
    Thanks in advance.
     
  2. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,578
    In general, you should drop the idea of using point light as a star. Resolution of shadows is limited by resolution of the texture, and for distant star individual shadow pixels will be too big.

    Additionally... beyond certain distance, camera stops rendering realtime shadows.
    https://docs.unity3d.com/Manual/shadow-distance.html

    So, you should create local directional light which will match direction of the star.
     
    Ryiah likes this.
  3. U2-84

    U2-84

    Joined:
    Oct 25, 2012
    Posts:
    5
    Hello, thanks for the response.
    Yes, I know that camera stops rendering realtime shadows beyond certain distance, but in this case I'm not looking for shadows on objects distant from the camera. The objects are close to the camera: they're just distant from the light source.

    About the directional light solution: I think it might work well on long distances, but getting close to the "star" object, the parallax effect would become too noticeable: I mean, the closer I am to the star, the more I should "rotate" the directional light because of my movements (see the pic).



    That would be okay for shadows on my character/ship, but I would see shadows moving on the static objects around me (because the directional light rotates): that's weird.

    Maybe I should make it so when I'm close to the star, I disable the directional light and use the point light, and then beyond a certain distance from the star, I re-enable the directional light?
     
  4. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,578
    This is a wrong approach.

    If your player is standing on the planet, you have to use directional light for the local scene. Because, depending on the scale of the scene, if you use point lights, individual texels in the shadowmap can be larger than the planet.

    If you're rendering planets, then you can use point lights. You can also use narrow spot lights aimed at planets and your scene specifically. Because most of the area around the star is emptiness, and there's no point in wasting pixel space of the map rendering nothing.

    Additionally, the player and the planets don't need to be rendered by the same camera. You can use camera stack technique on the same frame. The "bottom" camera will render solar system at small scale, with point lights as lower layer. The "top" camera will render scene the player experiences, with directional light. Conditions like player being in a shadow of the moon can be tracked manually.

    This is briefly demonstrated within "double precision spaceflight" demo I made long time ago.


    In this case there are several cameras, which render objects at different scale, depending how far they are, by first scaling them down.
     
    JoNax97 and Ryiah like this.
  5. mikeohc

    mikeohc

    Joined:
    Jul 1, 2020
    Posts:
    215
    Is it possible to achieve something similar without a directional light? I have a large interior scene with a roof that blocks the directional light from coming in. Imagine using the star of at the top of a huge Christmas tree to illuminate the large space in all direction.

    I baked all shadows on static object, but dynamic objects are simply too far from light to have any clear shadows. Is projector the only viable method for faking dynamic shadows in this case?
     
  6. Murgilod

    Murgilod

    Joined:
    Nov 12, 2013
    Posts:
    10,169
    Just use the layer system so interiors aren't affected by the directional light.
     
  7. mikeohc

    mikeohc

    Joined:
    Jul 1, 2020
    Posts:
    215
    I meant if i can't use directional light (blocked by a roof), how would I achieve local shadows that mimics a large point light(star at top of the tree)? I'm using shadowmask for static.
     
  8. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,578
    If the light is completely blocked by the roof, there are no shadows.

    If the light is visible, for example, thorugh a window, then you have a point where you can stick a fake light.

    Be aware that the scenario described in this thread is different from yours, because we're talking planetary scale here.
    in this case, a point light 152000000 kilometers away from the scene can and should be represented by a directional light.

    Your "large christmas ornament scenario" is very different from the sun, because the light is smaller. And will require a different approach.
     
    mikeohc likes this.
  9. mikeohc

    mikeohc

    Joined:
    Jul 1, 2020
    Posts:
    215
    I have a large point light (150+ range) in a large indoor space. I'm simply not receiving enough real time shadows for objects that are far from the point light. e.g. The gate below is dynamic, while walls beside it are static.

    I've been looking for a solution for getting dynamic shadows from a distant point light. What approach can you refer me to? Thank you.
    Screenshot (174).png
     
  10. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,578
    Well. I've checked scneario similar to yours:
    Point light roughly 100 units away.
    upload_2021-6-16_2-27-22.png
    In this case unity shadowmaps simply do not have sufficient precision..

    In this case a sane idea is to fake it. One way to do it is using a spotlight.
    Spotlight 150+ units away.
    upload_2021-6-16_2-33-2.png
    Those have sufficient precision.

    Keep in mind that this is builtin renderer.

    Basically your choices are faking it, using spotlights, or rolling out a custom shadow solution, which requires shader programming skills.
     
    mikeohc likes this.
  11. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,578
    To be more specific, if shadowmaps were rendered at a huge resolution in a floating point format like RFloat ( https://docs.unity3d.com/ScriptReference/TextureFormat.html ), chances are the precision would've been sufficient in this scenario. But it isn't being rendered in this format. And I do not beleive there's any sort of override for that.
    What's more, editor controls for point lights are artificially locked at a small range (can't set near clip plane to 70 meters, for example), and that makes it impossible to mitigate the problem.

    So a solution would be to roll out your own shaders for this particular spot, and you own shadowmap rendering routine... which can be incredibly painful to implement.

    So it would be easier to fake it with spotlights and the like.
     
    mikeohc likes this.
  12. mikeohc

    mikeohc

    Joined:
    Jul 1, 2020
    Posts:
    215
    Thank you so much. Besides spotlight, I thought maybe projector could fake the shadows as well, and simply to avoid projecting onto the dynamic object using a layermask. But I've found that method can be much more expensive.

    I tested out point light and spot light:
    Case 1 - Shadowmask - Baked Point Light - Realtime Spotlight
    LightTest_Shadowmask_BakedPoint_RTSpot.png

    Case 2 - Distance Shadowmask - Mixed Point Light - Realtime Spotlight
    LightTest_DShadowmask_MixedPoint_RTSpot.png

    Case 3 - Distance Shadowmask - Disabled Point Light - Realtime Spotlight
    LightTest_Realtime_Only.png

    Case 3 is ideally exactly what I aimed to achieve. But Then I run into this problem of having no shadows on far objects because the point light is disabled.
    Screenshot (193).png Screenshot (194).png
     
    Last edited: Jun 16, 2021
  13. mikeohc

    mikeohc

    Joined:
    Jul 1, 2020
    Posts:
    215
    So I tried Case 4 - Distance Shadowmask - Mixed Point Light with no shadow AFTER I baked - Realtime Spotlight
    LightTest_Shadowmask_PLNoShadow_RTSpot.png

    This method makes the lit area too bright as you can see where the ground meets the wall. If I disable the point light, I lose all distant baked shadows... I thought those are baked?

    If i bake the point light entirely, then I'd get results like case 1 again due to objects using different light mode. So I want to
    1) Use real time spotlight data within shadow distance
    2) Use baked pointlight data outside shadow distance - point light disabled to prevent lit area to be too bright.

    Screenshot (197).png
     
    Last edited: Jun 16, 2021
  14. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,578
    I've checked your situation in HDRP, and basically, there are two things;

    1. HDRP is perfectly capable of rendering distant shadows with precision. There's even 32bit mode precision for those in the settings.
    upload_2021-6-16_12-28-48.png
    ^^^ That's a point light.
    HOWEVER.

    Whether it is point or spot light, at a distance of 70..80 units, shadows are DISABLED and fade out.
    Because reasons, I suppose.
    upload_2021-6-16_12-30-42.png
    ^^^Also a point light.

    In advanced light settings there's a Fade Distance slider, but it does not affect the fade distance at all.

    You should probably report it as a bug.

    Of course it is brighter, because you have two lights and they add together.

    You have two possible solutions.

    Solution 1: In theory this could be fixed by using subtractive shadows for the spot. Apparently unity has those, but they do not work in HDRP.

    Solution 2: Place a blocker behind spotlight just so point light does not affect the area where spot light operates. This is going to be tricky to get right.
    --------
    Also, you're asking in a wrong forum, as General is not technically a support forum in the first place, and this is not even really related to the original question.

    Try starting a new forum thread in HDRP section.
    https://forum.unity.com/forums/high-definition-render-pipeline.386/
     
    mikeohc likes this.
  15. mikeohc

    mikeohc

    Joined:
    Jul 1, 2020
    Posts:
    215
    Thank you, this has been very helpful. I'll start a new thread in the appropriate section.
     
  16. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    You're talking about two different types of shadows here.

    The shadows being cast from the player onto other objects look ok or good. These are the shadows which detect when light is being blocked from hitting an object. This is done using a shadow map, and requires a depth buffer with adequate precision to be able to work effectively.

    The shadows on planets from your directional light are a different type of shadow. This type of shadowing simulates that surfaces on an angle from a light source receive less light from that source. This only requires comparing the direction normal of the light to the direction normal of the surface, and precision isn't an issue there.

    With that in mind, I would suggest having two different lighting setups in your scene, and applying them to objects (eg: through layering) based on whether they are the current play area, or distant non-active area. This kind of thing is very common in games, as we want the majority of our limited resources focused where the player is paying the most attention.

    - For distant stuff, have a point light on your star which doesn't cast shadows. Use this to get correct normal-based lighting for your distant planets. Ie: the bright side will align with the star. Giving up shadow casting on those objects is going to make little or no difference to your scene anyway - how often does a planet cast a shadow on something? If you do need that you can implement it separately, though.

    - For nearby stuff, have a directional light aligned with the direction from the star to the play area. This one casts actual shadows between objects. If this is a Mario Galaxy style "mini" solar system then a spotlight could also work well here, as @neginfinity already suggested. Note that the directional light will probably give you better resolution, as the shadow depth textures for those are fit to the camera rather than the light (ie: they maximise precision for just the area you can see).

    The tricky bit will be transitioning areas from one to the other without a visible "pop".



    Or you can take a completely different approach. Turn off shadow casting on your lights and have just the one point light on your star, then use some other shadow casting technique for objects where it matters. See Mario Galaxy again for an example of this. Their shadows are blobs and similar, and I think they always just point towards the center of mass of the current play area, because they're used as guides while jumping. You can of course do more than just a blob.

    And one more mostly different approach, is to use the same approach as with built-in lights but write your own light and shadow casting shaders to suit your specific use case. That will of course require building up a pretty intimate knowledge of how that stuff all works, but Unity does give you access to do all of that if you want.
     
  17. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,578
    Watch out for the thread date.

    The thing about mikeohc scenario is that he needs point light shadows in 150 unit range. Not in planetary range. His "Star" is a christmas tree star ornament, pretty much.

    HDRP should be capable of that. However, the coding of HDRP kills any shadows off beyond 75+ unit range, and that appears to be hardcoded. THere's a setting for it that is supposed to increase the maximum distance, but it does nothing.
     
  18. neginfinity

    neginfinity

    Joined:
    Jan 27, 2013
    Posts:
    13,578
    One other thing.

    "Distant dynamic light" is a scenario rendering pipeline should be able to handle.

    Because for a distant light you should be able to, say,. set NearPlane to 140 and FarPlane to 160 and have a high precision shadow in that range.

    Instead, whoever was designing the light source didn't really think of that scenario, and the maximum nearplane value you can set is measly 10 units.

    Which is annoying.
     
  19. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,620
    For depth precision, yes, you should be fine. I was referring to the area which must be covered by the depth texture. With a directional light the depth texture texel size is based on the camera's frustum, where for a spotlight it's based on the light's frustum.