Search Unity

  1. Unity 2017.2 beta is now available for download.
    Dismiss Notice
  2. Unity 2017.1 is now released.
    Dismiss Notice
  3. Introducing the Unity Essentials Packs! Find out more.
    Dismiss Notice
  4. Check out all the fixes for 5.6 on the patch releases page.
    Dismiss Notice
  5. Help us improve the editor usability and artist workflows. Join our discussion to provide your feedback.
    Dismiss Notice

Occlusion Culling Woes

Discussion in 'Editor & General Support' started by SteveJ, Jul 31, 2016.

  1. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    I'm having some major dramas with occlusion culling in a game that I thought would handle it really well (grid-based, 1x1 unit floortiles).

    Every level has the same occlusion culling settings, 0.95 being just below the size of the wall, floor, and roof tiles... right? (I've tried a bunch of variations):

    [​IMG]

    Some of the levels are perfect - no problems at all. But then I walk into a very simple rectangular room, and something like this happens (top-down view looking at the floor):

    [​IMG]

    All of the floor tiles, walls, etc right in front of the player get culled.

    Looking at the side views, you can see the visibility lines sometimes get "blocked" in front of the player, other times they make it to the roof, so you can see that, but no floor. Most of the time it's even culling the enemy in the room which is non-static.

    [​IMG]

    [​IMG]

    Any thoughts on what I'm doing wrong? I don't get it.
     
  2. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    Here's a video demo - two levels, both using the same occlusion culling settings (from post above). One level works perfectly, and the next is a mess.

     
  3. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    I think I just figured something out that was probably obvious to everyone except me...

    You need to turn off the camera occlusion culling if you're using baked occlusion culling? Now that I've done that, everything seems to be working MUCH better.

    EDIT: Actually according to the manual, that's NOT the case. So I don't understand why things work much better when I turn the camera setting off.

    There's still stuff I can't explain though - like why when I'm standing right in front of a wall (that is bigger than the smallest occluder setting) is the game still rendering what's behind that wall?

    [​IMG]
     
    Last edited: Jul 31, 2016
  4. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    I also suspect that the "Stats" don't properly take into account occlusion culling? Or at least I hope that's the case. Either that or the visualisation doesn't really work properly. Check out these two examples at opposite ends of the room. The visualisation shows that around the same amount of geometry is being rendered, but check out those stats!

    [​IMG]

    [​IMG]
     
  5. TTTTTa

    TTTTTa

    Joined:
    Mar 3, 2015
    Posts:
    1,299
    Click the "Set Default parameters button" on a scene-by-scene basis.
    If it still happens, delete the entire Occlusion folder and re-bake.
     
  6. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    ???

    I don't want to use the default settings.
     
  7. TTTTTa

    TTTTTa

    Joined:
    Mar 3, 2015
    Posts:
    1,299
    ????
     
  8. Shushustorm

    Shushustorm

    Joined:
    Jan 6, 2014
    Posts:
    820
    I had a similar issue a while ago and didn't know how to solve that either.
    Good to know about the camera setting then!
     
  9. ForceVFX

    ForceVFX

    Joined:
    Jan 21, 2011
    Posts:
    424
    For proper deductive reasoning we have to establish a 'Baseline'. that is what he is asking.

    Just for kicks, try even/larger numbers. it is that or something unique about those polygons/shaders, producing an inverse view matrix, which, I admit is bizarre.. use whole numbers and always power of 2, please try it?

    p-
     
  10. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    Obviously I've tried all the basic stuff - this isn't my first 70's themed disco.

    I was looking for advice from someone who knows how the occlusion culling system works and might be able to tell me why my specific problems above would be occurring. e.g. regardless of the parameters, if they're the same parameters on two levels which use the same geometry, then you would expect similar results, right? Not a level that works perfectly and another that's completely broken.

    If anyone has any advice specific to my issues described above, please let me know.
     
  11. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    Still hopeful that someone might have some advice on this one? Another perfect example below - why is Unity rendering a bunch of stuff outside of the small, closed room that I'm in? There's no possible "hole" in the geometry larger than 0.25 units (which is the setting on this example).

    [​IMG]
     
    Shushustorm likes this.
  12. Desutoroiya

    Desutoroiya

    Joined:
    Apr 26, 2016
    Posts:
    12
    I have the same problem, I have it with a room under the camera room. I tried to fix it occlusion area's, for some details it did the trick.
     
  13. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    For me, using occlusion areas produces DIFFERENT results, but they are still wrong.
     
  14. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    Alright... so I might have just found the answer to this, though I can't get my head around it.

    The walls in my game (for example) are imported with a scale factor of 1. Their local scale is also 1,1,1. Based on that, I concluded that my "Smallest Occluder" should be set to 1. Seemed logical based on my understanding of what "Smallest Occluder" meant, and based on the default setting of 5, that didn't seem like a stretch.

    I was then setting my "Smallest Hole" to 0.25 - assuming, given my scale of 1, that anything that large should definitely reveal the geometry behind it.

    Anyway, for S***s and giggles tonight I thought - Hey Steve! What if everything is just off by a huge factor for some unknown reason?!

    So... I set my "Smallest Occluder" to 0.1 and my "Smallest Hole" to 0.025, rebaked, ran the game, and... everything now works PERFECTLY.

    So what's the story there?

    This also now leads me to another question. In the doco there's discussion about the tradeoff of the amount of occlusion data that must be parsed vs the saving that it gives. Using the old figures, the bake was super quick and resulting in about 50KB of data (but the occlusion was next to useless). Now it takes a minute to bake (no worries) and results in about 4MB of data for an average level. So, the question, how much occlusion data is considered "a lot" of occlusion data?
     
  15. Zyl

    Zyl

    Joined:
    Jan 2, 2013
    Posts:
    70
    I don't know the actual algorithm behind Occlusion Culling in Unity, but it will probably use some kind of tree data structure. Given a camera position, it will then need to go down the nodes till it finds the one with the appropriate PVS (potentially visible set). It will depend on your scene how much of that data is the actual tree, and how much of it is just PVS-lists.

    If we just assume there are 100 references per node costing 4 bytes each, we could calculate 4MB of data = 4,000,000 / 400 = 40,000 nodes. If it's a binary tree you will then need lg(40000)/lg(2) ≈ 16 steps to find the correct node. If it's an oct tree it will be closer to lg(40000)/lg(8) ≈ 6. Either way that is not a lot, even if deciding which node to traverse is a bit costly (some vector math required).

    I might of course be completely wrong with everything I just said, though, but you always can (and should) try to tweak your values to balance size and quality. You divided your values by a factor of 10. Maybe multiply by 2 again and see how that goes.
     
  16. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    Turns out I spoke too soon. There are still levels that don't work using the 0.1, 0.025 setting. Same geometry as the levels that do work, same sort of layout of walls, floors, roof tiles, etc... just completely different results. I've found one level where NOTHING but the floor tile directly under my feet gets rendered sometimes when I'm walking around.

    Seriously over occlusion culling. Again, if anyone KNOWS how this should work, please advise (hint hint, someone from Unity who worked on occlusion culling would be nice).
     
  17. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    Changed the smallest hole setting to 0.075 and NOW everything that I've been able to test seems to be working correctly. Again though, in the context of my scale, I can't explain why 0.075 vs 0.025 would make any difference to the issues that were occurring, nor why it's 0.075 and not 0.75, given a unit size of 1.0.
     
  18. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    A related, but separate discussion - I'd love to hear people's interpretations of what they understand an "Occlusion Area" to be, and how they would use them in a scene.
     
  19. TTTTTa

    TTTTTa

    Joined:
    Mar 3, 2015
    Posts:
    1,299
    Your interpretation of what Occlusion Areas do will be different depending on what documentation you read.

    If you want to be mislead, read unity's documentation: http://docs.unity3d.com/Manual/class-OcclusionArea.html
    if you want CORRECT information, read Intel's description on what the purpose is of unity's Occlusion Area: https://software.intel.com/en-us/android/articles/unity-optimization-guide-for-x86-android-part-3#

    Mainly, I'm referring to the Unity docs lead you to believe you need an Occlusion area to occlude dynamic objects. This is not true. The true reason for Occlusion Areas aren't mentioned in the Unity docs.
     
  20. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    Oh, wow - nice link! Thanks for that :)

    The Unity documentation is pretty abysmal for a lot of these key systems. It's pretty slack.

    What I find is missing is use case data - e.g. how MUCH should a level be carved up into Occlusion Areas, how many is too many, where should the demarcations be, same goes for Light Probes, same goes for Reflection Probes, etc etc.

    Anyway... reading the Intel document now!
     
  21. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    I'm back to fighting my Occlusion Culling battle today. Seriously running out of steam on this thing though.

    SO... I *thought* that I had finally solved things once I discovered the issue of scale (i.e. a 1 unit wall must be considered 0.1 unit for the purposes of Occlusion Culling, or so it seems), however, during play testing I've just walked into a level which is not working and completely baffles me.

    Here's what the area looks like when in the scene view. You can see that there is NOTHING directly in front of the player when standing in this grid square.

    [​IMG]

    So, why does EVERYTHING in front of the player get culled when standing in this spot in-game? Same thing if I move forward a square, everything gets culled.

    These exact same occlusion settings are working 100% in other levels.

    [​IMG]
     
  22. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    Here's a little video to demonstrate just how bad it is in this area.

     
  23. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    And here's another level. EXACT same geometry placement, scale, etc. EXACT same Occlusion setup.

     
  24. TTTTTa

    TTTTTa

    Joined:
    Mar 3, 2015
    Posts:
    1,299
    What I would try doing is after you bake the occlusion culling for one scene, save the scene then delete the Occlusion folder from the library and do the same thing for the other scenes. If the issue goes away I would think that there is some issue with the cache in the library. So every time you bake a scene your starting with an empty Occlusion cache folder. It's possible when you bake one scene, it is getting some existing information from the cache and causing problems.
    Because the OC system is an external system for Unity, I don't know if a lot of people know exactly how the cache system works, except for the people who work at Unity and Umbra.
     
  25. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    I always delete the cache content manually after baking all my scenes because otherwise it contains about half a million files. I'll give that a try - deleting it in between each bake though and see what happens. At this point I'll try ANYTHING because I'm pretty much screwed if I can't get this to work.
     
  26. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    So, I managed to get to the bottom of the problems with occlusion culling. Everything is now 100% working in my project.

    The first big gotcha was that issue of scale. It definitely seems that the scale used by occlusion culling is off by a factor of 10. So if the "smallest occluder" in your game is 1 unit in size, you must set your occlusion "Smallest Occluder" to 0.1. If the "smallest hole" in your scene is 0.25 units, then the occlusion setting would be 0.025.

    The other issue (which turned out to be the answer to those last posts of mine) is that all of the geometry in the level appears to have to be "joined". This seems to be regardless of how you place your occlusion areas, etc. So in my project, for example, there were some levels where there were two dungeon sections, not joined by any corridors etc. This is because the player teleports back and forth between the two sections. I found that the occlusion culling in these areas was completely messed up, as per the videos above.

    What I ended up having to do was to create joining tunnels between these sections (that the player will never see), and block them off with the standard collapse geometry that I was using elsewhere already in the game. Once these joining tunnels were put in place, joining ALL of the level's geometry, then regenerating the occlusion data started working perfectly.

    Note also, for what it's worth, that I'm placing occlusion areas programmatically to cover only the specific geometry of the level, though I believe this only assists in reducing the amount of occlusion data generated, not in whether or not the "correct" results are calculated.

    [​IMG]

    [​IMG]
     
    Last edited: Sep 18, 2016
  27. eobet

    eobet

    Joined:
    May 2, 2014
    Posts:
    37
    I just begun looking into occlusion culling, and this is very interesting information, as I'm also making a 3D tile based game very similar to this in principle (although I'm not using that builder plugin I spy in the corner of the editor in the screenshot above).

    I hadn't turned on occlusion culling before, but your bug was easy to reproduce in Unity 5.6.0f2:

    [​IMG]
    Baked default parameters, two objects culled which shouldn't be.

    [​IMG]
    View from above without culling box ticked... so this is the view frustrum culling only now?

    [​IMG]
    View from above with culling box ticked... and now you can see the baking problems.

    [​IMG]
    All my "3D tiles" are 3x3x3 unity units (meters) large and triple checked to have applied scale in Blender.

    [​IMG]
    Using the above posters suggestions of 0.1 and 0.025 yields very long build times and even WORSE results for me, culling the entire room.


    So, I also don't have "connected" levels. Each "room" in my game is its own enclosed volume as you can see in the last two screenshots. But why would this matter? Also, what constitutes "connected" geometry? A single interesecting polygon? Can it be placed under ground with the normals facing down so the player never sees it?

    As I mentioned, my tiles are arranged in a 3x3x3 grid, so I'd be happy with occluding an entire tile, but putting both occlusion settings at 3 yields this, which looks way larger than my highlighted tile:

    [​IMG]

    My levels will be quite huge when I'm done, so I really need to use occlusion culling and I'm a newbie and it's amazingly lucky that I stumbled on this thread, but quite sad that no fix is available yet (and probably won't make it into 5.6.0). :(

    PS. I'm very surprised you have to bake culling in Unity at all, and I'm also very surprised that it can't be done automatically like ambient occlusion... wonder what the reason for that inconsistency is?

    EDIT: Just tried to add a flat polygon only viewable from beneath the level that intersects the other room and that did not help, culling is still borked to all hell in the player:

    [​IMG]
     
    Last edited: Apr 2, 2017
  28. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    Based on my findings (if they hold true for other cases), your "Smallest Occluder" would need to be set to 0.3, not 0.1. "Smallest Hole" is a bit more of a mysterious guesswork type property, but I found that based on my geometry, a factor of 25% Smallest Occluder worked exactly as required. Maybe try 0.075 in your case?

    FYI - I'm not using any builder or anything, so that doesn't factor in. Those controls you see are the ProGrids plugin which I use (for snapping) when manually laying out some pieces.
     
  29. eobet

    eobet

    Joined:
    May 2, 2014
    Posts:
    37
    Thank you for the reply! Could you please clarify programmatically are placing occlusion areas, as I've found no documentation (or tutorials) on this so far?

    Also, could you please post an example as what constitues a "connecting" tunnel? Wonder if I can make a script that basically bakes all occlusion and then hides my tunnels...
     
  30. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    I create a prefab of an occlusion area object that is about 1.1 x 1.1 x 1.1 units (so the end result overlaps everywhere). I then have this bit of editor code that auto-places an occlusion area in every grid square in the current scene/level (i.e. under every Roof tile for me). You can see the results of this in an early screenshot in this thread.

    Code (csharp):
    1.  
    2. private void PlaceOcclusionAreas()
    3. {
    4.     if (EditorUtility.DisplayDialog("Place Occlusion Areas", "Are you sure?", "Yes", "No"))
    5.     {
    6.         DpBuilderSource thisDpBuilderSourceCom = GameObject.Find("_DpBuilderSource").GetComponent<DpBuilderSource>();
    7.  
    8.         if (thisDpBuilderSourceCom == null)
    9.         {
    10.             EditorUtility.DisplayDialog("Problem", "DpBuilderSource does not exist.", "Ok");
    11.         }
    12.         else
    13.         {
    14.             GameObject oaRoot = PrefabUtility.InstantiatePrefab(thisDpBuilderSourceCom.Env_Occlusion_Areas_Root) as GameObject;
    15.             oaRoot.name = "Env_Occlusion_Areas_Root";
    16.             oaRoot.transform.position = Vector3.zero;
    17.  
    18.             GameObject[] gridSquares = GameObject.FindGameObjectsWithTag("Roof");
    19.  
    20.             foreach (GameObject thisGridSquare in gridSquares)
    21.             {
    22.                 GameObject thisOcclusionArea = PrefabUtility.InstantiatePrefab(thisDpBuilderSourceCom.Env_Occlusion_Area) as GameObject;
    23.                 thisOcclusionArea.name = "Occlusion_Area";
    24.                 thisOcclusionArea.transform.position = new Vector3(thisGridSquare.transform.position.x, 0.5f, thisGridSquare.transform.position.z);
    25.                 thisOcclusionArea.transform.parent = oaRoot.transform;
    26.             }
    27.         }
    28.  
    29.         EditorSceneManager.MarkSceneDirty(EditorSceneManager.GetActiveScene());
    30.     }
    31. }
    32.  
     
  31. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    In terms of connecting tunnels, my game had just a few levels where there were separated areas that the player could teleport between - i.e. there was no game geometry between those areas that fell within the scale of the occlusion parameters. I found that this completely messed up the occlusion for those levels and there was no fix that I could find.

    So, all I did was build tunnels between those areas that the player would never actually use, because they were blocked off with collapses (as shown earlier). What this meant though was that the occlusion script placed areas in these tunnels (because they were now normal grid squares with roof tiles). Once that was in place, occlusion baked perfectly.

    It's not a great workaround because it creates inaccessible areas in the game, but that really isn't too big a deal compared to the time I was wasting trying to fix the problem :)

    It's hard to see now that things are joined, but if you can picture the highlighted areas not being there, that's basically how it was originally. The blue lights are the teleports that are used to actually move between those "disconnected" areas.

    [​IMG]
     
  32. eobet

    eobet

    Joined:
    May 2, 2014
    Posts:
    37
    Thanks again for you answer.

    Through some more testing, it's was clear to see that 1 unity unit == 1 meter == 0.25 occlusion units. No idea why.

    Also, even though I added occlusion areas to all my tiles (with even a bit of overlap), no amount of occlusion unit tweaking seemed to produce a good result, and especially not in enclosed spaces.

    Can I ask how, exactly, the polygons in your hidden corridors are connected to the visible areas?
     
  33. SteveJ

    SteveJ

    Joined:
    Mar 26, 2010
    Posts:
    3,019
    All of my levels are made up of 1 x 1 wall tiles, floor tiles, roof tiles, etc. None of it is joined together at a mesh level.

    It's not about the geometry itself being "connected" so much as the occlusion areas not spanning "empty space"... or at least, that's the way it seems to me. It's the empty areas BETWEEN geometry that seem to introduce problems into the entire occlusion calculation.

    I don't know the science of it :) Only that eliminating "empty space", and using the 0.1x scaling rule, all of the occlusion culling in The Deep Paths works flawlessly.