The optimization and testing phase of the Unreal Engine 3D model creation pipeline is an important step in ensuring that your project runs smoothly and efficiently. It's during this phase that you'll make any necessary adjustments to your models and test them in the engine to make sure they're functioning as intended.
One of the key elements of this phase is performance. You'll want to make sure that your models are optimized for the Unreal Engine and aren't causing any performance issues. This may involve simplifying the geometry of your models, reducing the number of polygons, or using lower-resolution textures.
In this blog we'll cover:
- Levels of Detail (LODs)
- Texture resolution
- Channel Packing
Levels of Detail
Levels of Detail (LODs) are a technique used in 3D modeling for game engines to reduce the complexity of a 3D model and improve game performance. LODs work by creating multiple versions of a model with varying levels of detail and replacing the original model with a simplified version when it is farther away from the camera. This helps the game engine to focus on rendering the most important parts of the scene and improves the frame rate for the player. Implementing LODs involves identifying complex models, creating multiple versions of the model with decreasing detail, defining the transition distances, and implementing the LODs in the game engine.
- LODs can be generated in your 3D modelling software manually using a technique referred to as decimation, which basically means reducing the amount of polygons the mesh is comprised of. Some software have tools and plugins that can assist with this process.
- Alternatively you can have Unreal Engine automatically generate LODs for you, which you can then adjust the settings of in engine to ensure your model and it's accompanying LODs are befitting of the visual fidelity, performance and scenario required.
For more information on how to do this you can refer to Unreal's official documentation here : Setting Up Automatic LOD Generation | Unreal Engine 4.27 Documentation
If you intend for your model to be a static mesh and interactable with a player, it's likely you'll require collisions. These can be created several ways, both manually and automatically generated.
For complete control over both the volume and performance of your collisions you should consider creating these manually in your 3D modelling software. This generally comprises of adding encompassing meshes on top of your model where you'd like collision to exist, similar to a block out. These volumes then need to be named with the appropriate prefix, usually 'UCX_' inorder for Unreal Engine to recognise it as a collision volume. For a complete breakdown of this process check out Unreal's official documentation on creating custom collisions which can be found here: FBX Static Mesh Pipeline | Unreal Engine 4.27 Documentation
The second manual method for creating collisions can be done inside Unreal itself when opening your static mesh. You're able to generate simple collision volumes such as cubes, spheres and capsules which you can then scale up and down accordingly to fit your mesh. This can be a laborious process however, especially if you have many meshes to import.
Alternatively you can have Unreal Engine automatically generate the collision for your mesh, which it'll do one of two ways, either Simple or Complex.
- Simple collision will create the most basic collision volume that covers your entire mesh and is generally only good if you're importing really simple shapes such as cubes or spheres.
- Complex collision will create a 1:1 collision volume of your mesh but as it's generating collision based on each individual face and vertices on your mesh, it comes with a much higher performance cost.
Check out this link for a more comprehensive guide to creating collisions for static meshes: Setting Up Collisions With Static Meshes | Unreal Engine 4.27 Documentation
Managing the resolution of textures in Unreal Engine is crucial as it plays a significant role in determining both the performance and aesthetic quality of a game. Excessive use of high-resolution textures can slow down the game loading time and negatively impact performance, whereas utilizing lower-resolution textures can lead to a decrease in graphics quality. It is therefore essential to find the right balance between performance and visual appeal when adjusting texture resolution in Unreal Engine. For example, using 4K textures on small or seldom seen assets, particularly those that are less important visually for the player is generally a poor decision and the asset achieve the same goal using 2k or even 1k textures.
You can manually down-res your textures maps in Unreal Engine, which saves you needing to go back into your texture creation software and re-export. When opening a texture map in Unreal Engine you can go to the details tab and under 'Compression' you can set the 'Maximum Texture Size' to your desired resolution.
Here is a tutorial explaining this process - (1) Resizing Textures Within UE4 Reducing Memory Size - YouTube
Channel packing is the method of combining multiple textures into a single image, with each channel representing a different texture. This helps optimise texture usage and reduces memory consumption in Unreal Engine. By storing multiple textures in a single image, the engine only needs to store one image instead of many textures, improving performance. These channels can then be separated in the engine for use in different ways.
One example of channel packing in game engines is the use of Occlusion, Roughness, and Metallic (ORM) maps. These maps are commonly used in games to control the appearance of materials and objects, and they can take up a lot of memory if stored as separate textures. Using channel packing, the occlusion information can be stored in the red channel, roughness in the green channel, and metallic information in the blue channel of a single image. This image can then be imported into the game engine, where the individual channels can be split and used to control the appearance of objects and materials.
By packing the information from three separate textures into a single image, the game engine can use less memory, which can result in improved performance.
You can find more information on Channel Packing here : (1) What Is Channel Packing? | Channel Packing Series - YouTube
In addition to performance, you'll also want to test your models to make sure they're functioning as intended. This may involve setting up test levels or scenarios to see how your models behave in different situations. You may also want to use the Unreal Engine's built-in tools for analyzing performance and identifying any potential issues.
There are several methods and tools that can be used for testing and profiling the optimization of 3D models:
Stat Commands: Unreal Engine includes a suite of Stat Commands that can be used to gather information about performance and memory usage in real-time. This information can be used to identify areas of your project that may need optimization.
Profiler: The Unreal Engine Profiler is a powerful tool for analyzing performance and identifying areas for optimization. It provides detailed information about CPU, GPU, and memory usage, allowing you to see how different parts of your project are performing and identify areas that may need improvement.
Frame Time Breakdown: The Frame Time Breakdown tool provides a visual representation of the time it takes to render each frame in your game. This information can be used to identify areas of your project that may be slowing down performance and in need of optimization.
Streaming and Loading Analysis: The Streaming and Loading Analysis tool provides information about how the engine is handling data and assets as they are loaded and streamed into the game. This information can be used to optimize data and asset loading times, improving performance.
Real-time Hardware Skinning: Unreal Engine includes a feature for real-time hardware skinning, which allows you to see the impact of skeletal animation on performance in real-time. This information can be used to identify areas of your project that may need optimization, such as reducing the number of bones in a skeleton or using more efficient animation techniques.
By using these methods, you can effectively test and profile your 3D models in Unreal Engine, identify areas for optimization, and improve the performance of your game.
As you work on optimizing and testing your models, it's important to keep in mind the needs of your project. You'll want to strike a balance between maximizing performance and maintaining the quality and integrity of your models.
Ryan's top tips:
- If you have large models that will be visible from large distances away, consider using Imposters or Bill Boards to further optimize your model. An Imposter or Billboard is a 2D image that is used in game engines to represent a 3D object, typically for optimization purposes, by reducing the number of polyggonal triangles and vertices required to render the object.
- Unreal Engine has a 'Bulk Property Matrix' which allows you to change some settings on multiple assets at the same time, drastically reducing the time it'd take to do them manually one by one.
- Here's some useful Stat commands for checking performance
- Stat FPS - Displays the Frames Per Second (FPS) and Milliseconds (MS) which are measurements used in game engines to quantify the speed and smoothness of graphics rendering, where FPS refers to the number of times the screen is refreshed in a second and milliseconds refer to the time it takes for a single frame to be rendered.
- Stat SceneRendering - This command displays a real-time, on-screen display of various performance statistics related to the rendering of the scene, such as the number of draw calls, triangles, and materials used.
Once you're happy with the performance and functionality of your models, you can move on to the final phase of the pipeline: deployment. This is where you'll package and publish your project for distribution.