Search Unity

Question Ugly shadow flicker in large open world game

Discussion in 'General Graphics' started by funkyCoty, Aug 3, 2020.

  1. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    Unity 2019.4.2f1 -> I've got my camera's near clip at 1, far clip at 3000. shadow near clip is 1, and far clip is 250.

    unfortunately, I seem to get these really ugly artifacts on large areas of the game, is there anything I can do about this?

    video of the problem:
     
  2. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    How far from the world origin are you? The further from the world’s 0,0,0 position, the worse the floating point precision is, and the more chance there are for visual anomalies. The solution is to keep the camera or player at or near 0,0,0 and move the world instead.
     
  3. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    Ah man, I'm a few thousand out. Is there really no other way? The nature of my game (multiplayer with voxel terrain) makes this kind of difficult to deal with
     
  4. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    The problem is solved with the HDRP, but otherwise no. There’s no other solution for the built in renderers.
     
  5. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    :/ I know, I've looked into HDRP, and even tried to get my stuff ported to it. However, too many features are missing from shadergraph to actually make my shaders work in HDRP. And trying to "show generated code" and then just add in the missing bits is not easy, because they seem to do a bunch of uv packing (ignoring the fact its spitting out 10 thousand lines of nonsense).

    Shifting my world over wouldn't be so bad, if I didn't have to maintain networking and splitscreen. I wonder if there's an easier way.
     
  6. cosmochristo

    cosmochristo

    Joined:
    Sep 24, 2018
    Posts:
    250
    Are you sue it is due to distance from origin and not the different clip plane settings? What does it look like when you are at the origin?
    If it is due to loss of resolution due to origin distance then you can do object-shifting or continuous floating origin without HDRP. Not difficult.
    There is the unity wiki floating origin script or you can start with a simple continuous script like on here that can be applied.
     
  7. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    I verified bgolo's guess, it definitely is from going too far from origin. It looks fine until about 1000 units from 0.

    The script you link works by making a "root" transform, which is moved. Sounds easy, but this is non optimal memory layout for unity. And in my case, this is even 100x worse, because I'm constantly making new GameObjects, which would keep reallocating memory for transforms/gameobjects.
    Not just that, but this method does not work for splitscreen, or network'd games, easily. Both of which I need to support. That script is nothing how HDRP's "camera relative rendering" method works (by being tricky with transform matrices), its a lot slower and just not as useful.
     
  8. cosmochristo

    cosmochristo

    Joined:
    Sep 24, 2018
    Posts:
    250
    ok, good. I am a bit surprised the shadows are bad after only 1000 from the origin.

    Can you explain why? If you mean that it is better to have a small number of top level hierarchies then there is no reason why the reverse transform cannot be applied to more than one. I dynamically generate multiple root level hierarchies within the CFO framework and performance is very good.
    Also, there are some performance optimisations available in operations such as view/avatar proximity, collision detection and distance calculation, as described in this short article.
    Floating origin definitely works for networked games because it applies to each user's client side view. I have used it on a multiuser sim myself.
     
  9. bgolus

    bgolus

    Joined:
    Dec 7, 2012
    Posts:
    12,352
    And is unfortunately the only solution that works with the built in rendering paths that doesn't require completely separating game objects from the rendering and rewriting the shadow system yourself.
     
  10. cosmochristo

    cosmochristo

    Joined:
    Sep 24, 2018
    Posts:
    250
    hehe, "camera relative rendering" is pretty funny when you think about it.
    Rendering is camera-relative. This phrase says nothing, it is like a circular definition.

    Floating origin is generally applied before the rendering stage in the pipeline and is therefore independent of the rendering process.

    Although I used rendering in my publications as an example of how floating origin improves accuracy and quality, I also pointed out that it applies more generally to computation. It reduces the error in calculations, including rendering. Continuous floating origin minimises that error.
     
  11. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    I really hoped there was an alternative solution.. but like @bgolus mentioned, short of rewriting a bunch of the rendering I guess this is the shortest route to success. I went ahead and tried something similar to what you mentioned @cosmochristo, shifting the world around the player as seamless as I can. I'm not sure how I'm going to handle splitscreen like this, but I suppose I'll have to tackle that later.

    Here's a clip of it working.
     
  12. cosmochristo

    cosmochristo

    Joined:
    Sep 24, 2018
    Posts:
    250
    Triffic! One of the big issues that I have with Unity FO is it is restricted to HDRP. There is no reason why Unity could not provide FO support for all pipelines.
    That's very neat @funkyCoty, great work!
    I notice you appear to have a lot of grass collisions. One thing that may help is that with CFO you can nearly double the performance of proximity/collision tests. I have just updated the article on this: https://www.researchgate.net/publication/342510617_Position_Independent_Principle
    Additionally, note that one of the main performance issues raised wrt CFO is about the dirty hierarchy overhead from changing the root transform You may notice that I control this with .setActive true/false statements. This works well and, in tests on my corei5 laptop, ran twice as fast than without those lines. It would be nice if there was a way to tell Unity "I am doing a CFO translation, don't dirty the hierarchy!"

    Can you explain more about your split screen? I am sure people on this forum, or myself can offer some help. Keep up the good work!
     
  13. funkyCoty

    funkyCoty

    Joined:
    May 22, 2018
    Posts:
    727
    In my game on my ryzen 9, in the editor while non-deep-profiling, there is significant overhead that comes with even having all my chunk transforms within a single root prefab (~10 ms). This is much lower in final builds, but still significant. Simply moving them all to be the root completely eliminates this overhead, from what I've measured.

    For the solution I went with, I'm just doing a parallel transform Job to shift the ones I need. It's surprisingly not much overhead, and doesn't need to happen very often so I guess its alright for performance for now.

    It's just normal splitscreen. Two players can venture out in totally different directions. Maybe one will go to +10k and one will go to -10k. The world shift can only really follow one, or maybe the average between the two to try and keep things reasonable, unless I completely separate them into their own physics worlds and reduce my camera culling layers in half to reserve per player or something crazy like that, to allow them to overlap positions when far apart.

    It's just a small buffer of positions for nearby players which gets parsed by the vertex shader in grass. No real collisions, just visual.
     
  14. cosmochristo

    cosmochristo

    Joined:
    Sep 24, 2018
    Posts:
    250
    Does that happen even if you use something like:
    Code (CSharp):
    1. void Update()
    2. {
    3.     // do move transforms
    4.     SetScengraphActive(false);
    5.     // do something or nothing
    6.     SetScengraphActive(true);
    7. }
    Sounds similar. I dynamically change the hierarchy and at times have multiple root level hierarchies that all receive the same reverse transform. I only describe using a single root because it is easier to get the concepts across and compare to the transformation of each object one at a time.