HLOD + Streaming Octahedral Impostors -- (using MegaCity + Subscenes!)

So I've been looking at better/easier ways to approach LOD (and "scene-origin shifting") in Unity (for giant streaming open-worlds) ever since the MegaCity demo was announced.
It seems Unity's original "solution" to LOD (called "AutoLOD") was okay, but lacked a proper implementation.
Then MegaCity was announced, implementing a version of HLOD to handle some of this LOD work. After using it, however, I found I needed something more (besides just the ability to shift the world's origin automatically) -- I needed streaming imposters alongside HLOD (that also work with the new Subscene + HLOD implementation!)

I quickly found an article by one of the guys who made fortnite -- and realized Unreal offered a (free!!) solution to HLODs and imposter grouping + streaming already!! -- After the mind-blowing MegaCity demo, you can imagine how disappointed I was to see Unity missed a critical opportunity to top Unreal (again) by providing (free) streaming imposters (in-editor!) with its shiny-new In-editor Texture Streaming... :'(

The Legend of Zelda: Breath of the Wild clearly uses it too:

https://www.youtube.com/watch?v=geVgWMtbZNo|start=712

Doesn't that look nice? -- Go HLOD + imposter-streaming! :)

Anyway, below is an excerpt from: https://www.shaderbits.com/blog/octahedral-impostors (provided to illustrate the usage of streaming imposters + HLOD for giant streaming open-worlds...)
I don't think there is much awareness of this technique, so I am doing my part to spread the "know-how" to Unity and other independent game developers so eventually we can all create larger worlds:

SentimentalYawningFlyingfish

This comparison shows a 12x12 layout impostor for one of the main Fortnite pine trees. It holds up pretty well at a medium distance. The smallest frame count used in Fortnite is for the smaller farm trees which get by pretty well with only an 8x8 layout.

HLOD

HLOD stands for Hierarchical LOD. We use HLOD in UE4 to represent distant levels that are not actually loaded. We tend to refer to those as "Proxy HLODs". Originally, FNBR just used standard simplification for all the trees. That was causing HLOD meshes to be a ton of tris/verts and ti also meant the island did not look great while skydiving and popping was quite noticeable.

With the help of engineer Jurre de Baare, we made Impostors a built in part of HLODs. We added an option called "Use MaxLOD as Impostor" that tells an object to skip simplification and simply composite its data directly into the HLOD. This does bloat up sections because each impostor type needs its own material section.

All told, switching to impostors saved ~270,000 verts from being stored in always loaded memory (proxys never unstream) but it cost around 600 draw calls when viewing the whole island. That draw call cost mostly goes away from the ground.

This shows the impact on an individual POI (point of interest), the Ranger Station aka Lonely Lodge. Standard HLOD was costing almost 13k tris. Impostor HLODs dropped that in half and made it look much nicer.

The quality difference is fairly noticeable while skydiving in:

Another big reason to do this is performance savings when on the ground. Standing in wailing woods, enabling impostors saved around 500k triangles from rendering. This can be a several milliseconds on some hardware.

In terms of memory, they do cost significant texture memory. We saved the 270k verts from proxy HLODs, which is estimated to be around 10mb from memory. But each impostor in FNBR uses a 2048 basecolor/alpha and 1024 normal/depth. So each tree is 5.4 + 1.4 or 6.8mb of textures. There are currently 12 trees so thats ~81mb of textures. But the good news is that the texture data is streamable whereas the proxy mesh data is not.

For mobile we limit impostors to 1024 textures across the board. In the ASTC format, the 1024s use 341kb each. So on mobile the total texture memory cost is 8.1mb. So when you look at the numbers that way, switching to impostors DID save memory for mobile and everybody else paid a few megs to look nicer.


The "transition" between real mesh and imposter in Unreal.

The Process

WaryClearAustraliansilkyterrier
This gif shows the intersection being found on both grids, before and after unwrapping. This demonstrates how finding the triangle in 3D also finds it in 2D. Notice the small white dot which is the precise camera ray to the center of each sphere. The color of the triangle at that single point is where the weights are read from.


This image shows what the single depth offset is like, very similar to bump offset. Note that this works really well for very dense trees where the depth mostly forms a cohesive shell. For very sparse and busy trees, this single offset will show lots of noisy artifacts.

Where can I download this??

Sadly, this is Unreal-only (again)... :'(

However, the source is actually (freely available!) here in case somebody wants to try their hand at porting this to Unity:
https://github.com/ictusbrucks/ImpostorBaker

I'm more of an artisty-programmer than a programmy-programmer, so I'm useless when it comes to programming heady stuff like this, but that doesn't keep me from wondering if -- for example -- the HLOD system used in MegaCity might be compatible with this system?
If so, the new in-editor Texture-Streaming in 2019.1 could really help in making this real... D:

9 Likes

Try https://github.com/xraxra/IMP

4 Likes

[quote=“andrew-lukasik”, post:2, topic: 742223]
Try https://github.com/xraxra/IMP
[/quote]

Heh, I actually forgot about this – Thanks! :slight_smile:

It’s a great pre-ShaderGraph / pre-MegaCity-HLOD implementation.
It’s still not HDRP / LWRP capable yet though… This totes needs updating… D:

Amplify Impostors offer a solution.

I'm so glad IMP exists :) However my trees always look a little bit off, but hey it's free

Now that an HLOD implementation was included in MegaCity, and Imposter support is being looked at in URP -- I wonder what plans Unity has to handle HLOD for floating origin worlds?

Anyone @ want to chime in?

5 Likes

In the case of imposter, it's important that the imposter can be generated at runtime.

If you do not create an imposter at runtime when you remove one of the trees in the forest, the missing tree may appear when you are far away.

[quote=“kite3h”, post:7, topic: 742223]
If you do not create an imposter at runtime when you remove one of the trees in the forest, the missing tree may appear when you are far away.
[/quote]

Ideally, the imposter would simply be another layer of the LOD system for the gameobject. Unity’s LOD system seriously needs to be reworked, since more complex LOD systems (like HLOD), are becoming infinitely more common.

Looking at UE5, taking a model straight out of Zbrush into the game engine is going to become possible too.

I wonder if @ has any plans to fight back with its LOD system?

2 Likes

Also, to add onto my previous comments about the LOD system -- a programmable shader/culling system (kind of like ShaderGraph) which would handle tasks like LOD, shader switching/object fades, and culling based on specific values/tags would be great too.

Just saying.

2 Likes