Search Unity

Massive city block project taken over, need advice how to handle performance (overview, FPS, VR)

Discussion in 'Editor & General Support' started by NUKKschocke, Nov 21, 2018.

  1. NUKKschocke

    NUKKschocke

    Joined:
    Oct 17, 2018
    Posts:
    34
    TL;DR: How would you handle performance / lighting optimization in a massive scene that needs to look good from far away, close up and in VR when the assets are not game engine optimizable and there is a time-of-day adjustment option at runtime (the sun being the only light in the scene)?

    Full story: (or as comprehensive as I can make it in the first draft)
    A colleague and I have recently taken over a massive project that's already been handed down twice before. The project is an architectural pre-visualization application for the refoundation of a large chunk of land around an unused airport. The application is used by architects, planners and engineers to elaborate on financial, structural and visual decisions (among others).

    There are different camera modes (ways to view the scene):
    • overview: used to see the entire area from an eagle-eye's view (orbit, pan, zoom)
    • pedestrian: dropping into the area from overview and using normal PC controls (WASD, mouse), the user can walk freely through the area
    • VR: like pedestrian, only with a HTC Vive and typical VR input
    Basically what this means is the scene needs to look good from far away AND in close up and be performant enough across the board to enable a 45fps minimum VR experience.

    Here's the kicker:
    As this is a project that concerns the public as well, presentations are held where uninvolved (regular) people can test the application themselves. This is meant to generate public interest and favor. What this entails is that the graphical quality and fidelity need to be high enough to create a bit of a "Wow!"-factor.
    However, the company generating the 3D assets is mostly specialized in architecture modelling, meaning the assets are not optimized for use in a game engine (f.e. 28k tris on a building in LOD0) and will stay that way.
    As the profiler informs me is true, this leads to a high performance cost in rendering both on CPU and GPU passes. (I will add pictures later. Scene is currently baking stuff)

    After having spent quite some time refactoring, improving and simplifying the codebase, adding to the existing featureset in preparation for a few public presentation deadlines and trying to optimize materials and import settings, we are now in the process of trying everything we can to improve rendering performance.
    This is where we (or specifically I) have hit kind of a brick wall.
    I've spent the last three days reading through tutorials and manuals on everything to do with lightmaps, global illumination, Enlighten, shadows, quality settings etc. While I still don't feel like I've even understood the basic concepts to a sufficient degree, I managed to figure out the following:
    • An adjustable time-of-day and subsequent variably rotating directional light means that baked shadows/lighting is not an option -> Realtime Lighting / Realtime GI
    • The use of STIX grass shaders (and maybe even the SpeedTrees?) severely impact performance
    • It does not seem possible to confine realtime GI precomputation to a specific area of the scene (i.e. compute pedestrian-accessible area in higher resolution than full overviewable area)

    We have already set up occlusion culling and fiddled around with batching (which I am not sure we are doing correctly). Today I've let unity generate a LightingData asset for the scene (took about 3 hours, give or take).

    So here's my questions:
    • What's the best way of handling large scenes with lots of geometry in terms of marking them static, batching and lighting them (with the aforementioned conditions)
    • Is there any way generate lighting information in a high resolution for only PARTS of a map?
    • Am I CPU bound or GPU bound? Because I honestly can't tell from the profiler at this point.

    I wish I could go into more detail because communicating the size of the scene and the effect of this issue on implementation and asset handling via text just doesn't really cut it.
    If you have any further questions, please feel free to ask them and I will answer as best my NDA allows me.

    I have attached five pictures of the profiler (from a built version, so there should be minimal editor overhead). As I am not sure if these will help any, I'll probably update this thread in the coming days to include further information. It's getting to be that time. :D
    1. overview, default position, 4.2k batches (saved by batching: 8.4k), Tris: 3.6M, Verts: 7.8M
    2. pedestrian, low load position, 1.7k - 3k batches (s.b.b.: 1.1k), Tris: 2.7M, Verts: 4.1M
    3. pedestrian, high load position, 1.9k batches (s.b.b.: 4.5k), Tris: 3.9M, Verts: 5.7M
    4. VR, low load position, ~4k batches (s.b.b.: 1.7k), Tris: 4.9M, Verts: 9.8M
    5. VR, high load position, 7.4k batches (s.b.b.: 9.8k), Tris: 10.7M, Verts: 17.3M

    profile-01-overview-base-position.PNG profile-02-pedestrian-low-load.PNG profile-04-pedestrian-high-load.PNG profile-05-VR-low-load.PNG profile-06-VR-high-load.PNG
     
    Last edited: Nov 21, 2018
  2. NUKKschocke

    NUKKschocke

    Joined:
    Oct 17, 2018
    Posts:
    34
    Bump. Any ideas, anyone? Some simple tips or links to tutorials / assets that might help would already go a long way.
     
  3. karl_jones

    karl_jones

    Unity Technologies

    Joined:
    May 5, 2015
    Posts:
    8,281
    Sounds like you want some LODs. I see you say LOD0 is 28k but what is the lowest LOD? I don't know what it looks like so im making some assumptions here.
    First, you could LOD all the large complex geometry so that it is much simpler when far away, you don't need high detail when you can't see it! https://docs.unity3d.com/Manual/class-LODGroup.html
    If possible you could even use imposter textures.

    If thats not enough and the block is large and complex then its worth considering more advanced techniques such as quadtree based lod systems. Several years ago I managed to get 30,000 buildings running using this technique however it requires a lot of pre-processing the assets. Essentially you combine the lower quality LODs into a single mesh and then bake all the textures into less, maybe even one. Then each quad can be a single draw call, as you get closer to the object it is quartered into 4 meshes and those 4 meshes then do the same until you get to the original model.
    This means you have a lot of data so then need to look at streaming it in, AssetBundles are great for this.
     
  4. NUKKschocke

    NUKKschocke

    Joined:
    Oct 17, 2018
    Posts:
    34
    First of all, thank you very much, Karl. :)
    Yes, we have LODs and the lower LODs are very much easy on the processor (aforementioned buildin has 28k Tris on LOD0 and 88 on LOD1. I've talked to the asset makers about making an intermediate LOD and it's being discussed).

    From what you've described I am not sure if we can manage implementing a quadtree solution with the way the project has so far been handled (before we got our hands on it) and the amount of time needed to implement it into the workflow, especially with non-gaming-oriented assets. But I will definitely read up on it and brush up on the AssetBundle pipeline.

    Can AssetBundles be used to f.e. load/unload a whole lot of geometry at runtime?
    As an example, in overview mode we use satelite images and billboard trees to display the far away environment around the district and low polycount buildings in the industrial areas outside of the walkable areas (though there are quite a few small objects like crates and cable drums strewn about the place which we might get rid of in the near future).
    Could we -using AssetBundles - unload all that geometry when switching into first-person view and reload it quickly enough to not be visually jarring when going back to overview?
     
  5. bigmonkgames

    bigmonkgames

    Joined:
    Mar 16, 2016
    Posts:
    12
    Maybe you could break up the scene in zones and cull out zones based on position current zone they are in?
     
    joshcamas likes this.