Discussing the Possibilities and Drawbacks of Unreal Engine 5's Nanite

Simon Verstraete talks about the latest update from Epic Games and explains how the cliffs were created using Houdini and the brand new Nanite system in Unreal Engine 5.

In case you missed it

You may find these articles interesting

Introduction

The last time we spoke I wrote a breakdown of the procedural crystals in Houdini, since then I have continued creating Houdini-related projects. Together with SideFX, we started creating Project Titan, which is a learning project that you will hear more about in the future. With that project, SideFX wants to show a bigger view on creating environments and other things with Houdini and Unreal Engine.

For my personal projects, I have been making more videos on my YouTube channel and other experiments. Such as my latest test project with Unreal Engine 5.

First Look at Unreal Engine 5

Overall it is super impressive what the team at Epic Games created. This is an amazing leap in the right direction for the future of creating games. With Lumen and Nanite, it will help a lot to make games faster and spend less time on optimizing models, like LODs, baking, etc.

What I got most excited for is Nanite, this opens possibilities for generating large complex procedural assets and scenes that you can open in Unreal Engine 5 and it will take care of a couple of things to make sure it runs nicely for a game. Especially when you have the Houdini plugin, called Houdini Engine, so you can directly open procedural tools in the game editor to generate what you need.

Working With Nanite

Nanite in Unreal Engine 5 is a virtualized geometry system, this makes it possible to have high-poly meshes in the scene. For the user, it is just a toggle that they can enable to get Nanite working on that geometry.

If you enable this when importing geometry it will prepare your mesh. The mesh will be analyzed and hierarchical clusters will be created. These clusters are groups of triangles and depending on the detail you need in the scene, they will change the density or detail of these clusters. Here is an image of the cluster and if you move around in the scene you will see that they change to get the correct detail for the scene.

Let’s get a bit more technical, Nanite has its own render pass and bypasses the use of draw calls. Draw calls are now very important to keep an eye on for the game performance. In Nanite's own render pass, one of the first things it is doing is checking on the culling, this will check what geometry needs to be rendered based on the camera view. So not all instances or triangles of a mesh need to be fully rendered. This is then also in combination with the cluster swapping of the meshes. The culling combined with the cluster will reduce the number of triangles a lot.

Here is also an example of that culling, you might see this as well when you build something in Unreal Engine 5. You can see from the outline that parts are not rendered.

Then it is being rasterized where your scene with 3D meshes gets converted to pixels on a 2D screen. This is a quick explanation of what is going on in the background. If you want more detail on it I recommend taking a look at the Unreal documentation and Emilio's breakdown.

Chances are high that later the team at Epic will give talks and more breakdowns of it. They might also change things along the way since the official release for Unreal Engine 5 is planned for next year.

Creating the Cliffs

In Houdini, I generate 2 high-poly meshes and with those meshes, I also wanted to test if I could only use the vertex color to save the albedo color instead of using textures. So since Nanite handles a high amount of polygons, why not try to save the color in the vertex, then you might not even need a texture at all. This can also be beneficial when generating this procedurally with Houdini.
 
The first mesh is the big cliff rock. Here I started with a base shape, this shape is a circle with noise added to it except the height. The shape gets then extruded to create details here on the sides later. Then for variation, I scatter around points and copy that shape on the points. This is then the blockout for my rock and the only thing left is adding the rock shapes and details. After that, the mesh needs more polygons for creating the rocks, and a voxel is used for that. The voxel will increase the polycount a lot, this is quite similar to ZRemeshing in ZBrush for example. With the Triplanar Displace, you can create the final details. This will project a Height Map on the mesh and displace the shape. It also has the option to project a Color Map as well, so here you displace the model and add colors at the same time. Here you could use the Megascans assets for this.

The second mesh is the ground geometry, this one requires a bit more work. For this, a terrain system is used (a.k.a. Heightfields in Houdini). With a heightfield created, the first thing to do here is to project shapes onto it. Here I used the shapes from the big cliff. The next step would be blending this.

For blending the shapes, you can use blur and blend that back so you don’t lose too much detail or supporting area for the cliffs. Blurring the shapes will remove details and distortion by noise can create back some interesting details. Here is an example of that.

As a final touch, an Erode node is used. This will do a simulation on the terrain like water and debris falling down. Here it is important to have a good scale and resolution of the terrain, this will influence the results you are getting.

The terrain is now done and it gets converted to geometry so it can then be used with Nanite. With the terrain converted, this is also a high-poly mesh, the mesh itself has a lot of details from the Erode. The last thing I added here was the vertex colors, if you look at the attributes you have data from the Erode node that gives you maps like water and debris. These are used to create interesting color variations on the model. Here's how to get a mask:

And here's the process of getting all the masks and blending them with colors.

Once this is all done the mesh is exported as FBX and imported into Unreal Engine 5 with Nanite enabled.

Adding Houdini to the Mix

Overall, Houdini is great for generating large complex scenes and automate tasks. Like often studios using Houdini would procedurally generate 80% of their worlds. It saves a lot of time for the artists so they don’t have to place and build everything from scratch.
 
There are great examples out there like Far Cry 5 and Spider-Man for PS4. In both games, a large part of the open world was generated with Houdini. Artists can use curves or place cubes where things need to be and a procedural handles the rest, like placing models, deforming the terrain, creating new geometry, etc.

The main idea here is that a base scene or world is generated for the artists, so they don’t have to place and create everything from scratch. With a base scene created for them, they then can do more final manual tweaks to fit the game or the scene better, this can be done for gameplay reasons.

Content creation could also demand more work if you are going to build a scene where all meshes have these high-poly details. Now we often fake details in normal maps but if it needs to be in the geometry then you would need to model or sculpt these details as well. Houdini can play an important role here by automating the process of adding surface or material details in the geometry.

Nanite's Limitations

For the scene I made with the rocks, it worked like expected since the rocks are bigger shapes and they're not thin surfaces. There are some limitations when it comes to thin surfaces, one of them is the high amount of overdraw it causes. So with Nanite, it is always looking to optimize and reduce or remove triangles of a mesh. With a thin surface, there will be barely any triangles to remove, so a lot of triangles are rendered and overlapping. There is a debug mode for this which is like a Heat map to show areas of high overdraw.

Here's an example of a high amount of overdraw with thin surfaces like grass:

Here is an image of the rock scene and you see a huge difference in the overdraw:

Another thing to watch out for with thin surfaces is the auto reducing or clustering of Nanite, you might see some deforming of the mesh when you see it from afar.
 
Nanite currently has a few limitations. The team at Epic is still looking into making more things possible with Nanite since this is still an early access version of Unreal Engine 5.
Here are a couple of other limitations:

  • deforming mesh with material, like world offset
  • vertex paint on instances
  • opacity modes

There are more things and it could be worth checking the website if you are planning to make scenes or a game in Unreal Engine 5.

Solving the Issues

Epic Games are spending a lot of time on the compression of geometry. On their documentation, there is an example of a static mesh and a Nanite mesh both having 1.5M polygons.

As you can see, the static mesh takes 150MB and the Nanite mesh takes 19MB. This is a big difference, of course, the lower in poly count the smaller the difference will be. Another advantage of Nanite is that you won’t need LOD’s and even in some cases normal maps, which will also save you space and time when making a project. Just because you can have these high-poly meshes in the scene doesn’t mean everything should be high-poly meshes, you will have to find a balance or workflow that works best for your project or studio. Like some techniques we use to do can still be useful or even combine things like using a detailed normal map on the Nanite meshes to create fine details that can look sharper rather than spending more and more polygons.
 
Also, SSD are going to become imported to handle a large number of meshes and the swapping of the details of the cluster. This will make it possible to do impressive things like swapping to a whole new environment in just a second as shown in the latest demo.

On the other hand, as developers, we still need to create these original meshes and this, in general, could take more space if all your assets are insanely high in polycount. Depending on what 3D modeling software you use, you might have more trouble with handling these high-poly assets.
 
For the end-users I hope we don’t see that much increase in file sizes, we already have games going to over 100 GB. Cloud platforms like Stadio, PS Now, or Xbox won’t have the issues with the sizes of the games but will have other struggles to figure out.

Simon Verstraete, Technical Artist

Interview conducted by Arti Sergeev

Join discussion

Comments 0

    You might also like

    We need your consent

    We use cookies on this website to make your browsing experience better. By using the site you agree to our use of cookies.Learn more