Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Occlusion Culling - Multi Scene...

Discussion in 'Scripting' started by joshcamas, Feb 27, 2020.

  1. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,276
    I've been using Occlusion Culling in my game for a while now, but now it looks like it won't actually work for my game, due to how Unity handles Occlusion Data.

    My game loads a "world" scene, which is essentially a master scene. This is loaded when the player is first spawned into the world. I then have multiple "map" scenes, which load additively. Only one map scene loads at once.
    Finally, I have hundreds of "cell" scenes, all of which load depending on position and what map is loaded.

    I've always just baked occlusion culling on the world scene, since it's always the master scene and I just used the occlusion baker window. However, now that I'm building a tool that automatically generates occlusion culling data per map, I'm realizing that this seems impossible!

    Unity seems to only load OcclusionData when the first scene is loaded, aka scene is loaded in non-additive mode. In other words, in my case, the world scene. This is terrible news, since that means I cannot swap occlusion data without completely wiping out my world scene, which is something my game is not designed to do at all.

    Does anyone happen to know of any tricks to allow for swapping of occlusion data without completely resetting all scenes? My only idea involves marking all root objects of the world scene as do not destroy, then just using the map scene as the active scene, and when the game ends, unmarking all root objects. Absolutely hacky, but it may be the only way to do this due to Unity's ancient Occlusion Culling implementation...


    Another interesting thing is not being able to see the status of a asynchronous occlusion bake via scripting. Unity has a little ui at the bottom, but I can't find where that ui is managed in the source code, suggesting it's handled on the C++ side of things for god knows why. Fun!
     
    Last edited: Feb 27, 2020
  2. TurboHermit

    TurboHermit

    Joined:
    Dec 20, 2011
    Posts:
    40
    Hey there, I'm currently working on the same thing. So far, experimentation doesn't yield the results I want yet, but maybe you're interested in seeing the progress or have some ideas yourself!

    My idea was to see if it's possible to baking occlusion culling per scene and then combining it all into a single OcclusionCullingData asset that would be loaded in the main scene. This way you only have to rebake dirty scenes and recombine the data. Of course, there's no exposed API for OcclusionCullingData, so I'm trying to extract and set data through serialized objects.

    My current process looks like this:
    1. Get the OcclusionCullingData.asset file through AssetDatabase.Load or through EditorGUILayout.ObjectField as a UnityEngine.Object
    2. new SerializedObject and pass the OcclusionCullingData Object as parameter
    3. Iterate through the property names using SerializedObject.GetIterator and SerializedProperty.Next
    4. Check the names of the properties and use that info to get/set what you want
    I'll let you know if I make any progress with this.
     
    joshcamas likes this.
  3. esustachah

    esustachah

    Joined:
    Dec 21, 2018
    Posts:
    8
    Hello guys,

    I've been working on an open world game, and also encountered this problem a few weeks back. I'm sharing my piece of experience in hopes it helps.

    After doing some research I found that the solution to this problem is to simply set the right Scene as Active depending on your world location and nearby Scenes.

    You'll need to arbitrarily define "Scene Occlusion Areas" which will be tied up to specific Scene Locations in the world; these Scenes will contain the Occlusion Data for themselves as well as the neighbouring Scenes.

    As Scenes are loaded additively at run time, these are checked to see which is the nearest Key Scene with Occlusion Data based on player proximity, then, it is set as Active, forcing Unity to Load the corresponding Occlusion Data for the Currently Loaded Scenes.

    In order to bake the Occlusion Data you'll need to open the Key Scene that will hold the Data as the principal, then you'll add the neighbouring scenes that will be baked. Proceed by baking Occlusion. Move to the next Key Scene and repeat.

    Here are some Links with the intended workflows.

    https://docs.unity3d.com/Manual/occlusion-culling-scene-loading.html

    https://www.reddit.com/r/Unity3D/co...lling_does_loading_a_scene_addictive/flxikg3/

    https://docs.unity3d.com/ScriptReference/SceneManagement.SceneManager.SetActiveScene.html

    Hope this helps!
     
    joshcamas likes this.
  4. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,276
    Very interesting! In this case (using a square chunk method), you end up with 9x the data though, right? Seems quite inefficient, but sounds like the only solution we have!
     
  5. esustachah

    esustachah

    Joined:
    Dec 21, 2018
    Posts:
    8
    Yes it is inefficient but it works (yeiii), sadly it was the only way to do occlusion culling for neighbouring Scenes that comes to mind for a huge open world game.

    For my case, I load 4 scenes at a time (large terrains), which are exchanged based on the player world position. Indeed occlusion Data is then loaded anchored on each "cell pair", and the active scene is then assigned based on which quadrant the player is standing, which holds the data for the other 8 surrounding scenes (So my 4 scenes are always covered).