Content Optimization
The main part of any virtual scene is geometry: meshes imported from 3rd party editor and objects created by means of UnigineEditor and built-in tools (e.g., Terrain, Grass, Water). Using objects with complex geometry and/or a great number of objects as is usually leads to application performance drop. In addition, irrational use of light sources can also raise performance issues.
Articles in this section describe main methods that can be used to optimize geometry and lighting in your scene, and, therefore, increase the performance of your project.
See Also
Video Tutorial on Content Optimization:
Optimization Workflow#
Before you start optimizing your scene, you need to know where the problem is.
-
Enable profiler in runtime.
Decide on the profiler you are going to run:
- Performance Profiler may be enough for general assessment and first look. Run the application instance and use the console command show_profiler 1.
- Microprofile should be used for a more detailed research. Enable it in the project options before running the application instance or use the console command microprofile_enabled. To visualize the profiling data, follow these instructions.
Enabling profilers in the editor is also possible and may be helpful for the content-related assessment. However, running the profiling tool in runtime provides a more reliable assessment.
-
Define the target.
The most common optimization marker is that each frame should take no more than 16.66 ms, which means that your application aims to run at 60 frames per second (fps). Compare it with the current values available in profilers.
Data in Performance Profiler -
Detect the problem side: CPU or GPU.
In Performance Profiler, check the Total CPU and Total GPU Performance Profiler values. In Microprofile, assess the time spent by the engine on CPU and GPU. If the time spent on either of these sides exceeds the target time limit, it definitely requires a closer look.
- If the issue is CPU-bound, add markers to code to make the details visible in Microprofile as well, detect bottlenecks in your code and optimize the logic.
- If the issue is GPU-bound, apply the suitable content optimizations available in this section.
Some of the recommendations may be inapplicable to your project and some of them may not provide the desired results, therefore use common sense and compare the results before and after optimization activities to make sure that they are useful for your case.
Check the number of triangles#
These values are provided by the Rendering section of Performance Profiler.
For a faster scene the total number of triangles should tend to a possible minimum (in practice, not exceeding several millions of triangles).
If your scene is well beyond these limits, you might consider applying some of the optimization techniques listed here.
Visibility Settings#
Use common sense and personal experience to decide on what values should be set for various objects in your scene: for example, small objects are not discernible at a big distance, why setting an infinite visibility for them. Based on this you can:
- Configure visibility distance for all objects globally or individually.
- Configure levels of detail to simplify a model at a distance, thus reducing the rendered number of triangles.
- Consider using occlusion culling to avoid rendering of objects that are hidden behind a bigger object.
Optimize Your Model#
Assess the approach that was used at creating the models and consider if they can be optimized for a better performance when rendered in real time:
- Don't create one inseparable mesh for a big model (such as a building) uniting a great number of elements (doors, poles, stairs, etc.), otherwise you won't be able to use various optimization tools available in the engine (such as clusters and clutters that can speed up rendering of numerous identical parts and reduce performance costs).
- Use impostors wherever applicable (background/distant vegetation and some other distant objects quite often don't require geometry, so you can just replace the model with a flat square photo of the model — just two triangles, it's definitely less than any model that you have).
- Make sure that the potential of a material is used to the full extent: for example, small bumps and curves may be implemented not as the object geometry, but using the normal map (displacement sample). Check Art Samples to find more ideas.
- Inspect the content in your scene carefully, you might have added objects that you don't use (hidden somewhere inside a building or underneath the scene). Remove them, otherwise they'll also affect performance.
Simplify Shadows#
The number of triangles rendered for shadows also can be significally reduced in a number of ways:
- A shadow is a projection of a model that's why a shadow cast by a model contains the same number of triangles as the model. But any shadow definitely doesn't require so many details. Use the most simplified LOD to cast shadows: enable shadow casting by that LOD and disable it for all other LODs.
- Shadows are not necessarily required in the distance. Configure the shadows visibility distance.
- Disable shadows cast by objects and enable screen-space shadows to check if they will be enough for your project. If you are dissatisfied by screen-space shadows at a short range, consider using them starting from a certain distance and configure shadow casting for all objects correspondingly.
- Use static shadows for objects that won't change their position, and the light source won't also change its position.
- Use shadow settings sparingly (such as Filter noise and Penumbra noise)
Optimize Light#
Dynamic lights affect performance, therefore develop a habit of replacing them with static lights or even faking them wherever possible. This is primarily applicable in indoor scenes and scenes with unchanging light conditions. UNIGINE has a set of tools and approaches for that:
- Voxel Probes contain indirect light baked from static light sources, so that an object moving inside the probe is shaded appropriately.
- Billboards, Volumetric Objects may represent a light source visually, but without providing any actual illumination.
- Static Lighting may be used for night scenes. You can find a simplified example for that in the Lighting section of Art Samples.
- Lightmaps store brightness and reflected color of lit surfaces and can be used in static scenes.
Use Proper Shaders#
Use shaders sparingly and only for intended use: for example, using the Alpha Blend shader would cost you more performance than using a shader for non-transparent materials, and if your material is actually non-transparent you'll use extra resources in vain.
You can use the corresponding helper to highlight the surfaces in the scene that use transparent materials (Helpers -> Transparent).
- Use non-transparent materials as much as possible.
- To imitate elements that have holes (such as wire mesh or picket fence, or torn fabric) use Alpha Test material.
- Use Alpha Blend for glass only.
Water#
It makes no sense to use the Global Water object when you only need a small pond or a river, and you'll never go underwater — the object will consume resources, but you won't make the benefit of the features it provides. Water Mesh will be enough in this case.
If your scene indeed needs the Global Water features, use the corresponding optimization techniques.
Other Rendering Optimizations#
- Optimize landscape terrain, consider using compression for the Landscape Layer Map to ensure smooth streaming.
- Configure global settings appropriately: for example, set the render settings to the minimum acceptable ones, do not use ultra settings for the options you don't use in your project at all.
- Configure streaming settings: limit the memory available to the application to avoid crashes and find the balance between performance and memory consumption (Settings -> Streaming).
- Disable buffers that you don't use.
- Use the Cleaner tool to detect unused resources stored in your project folder and remove them to reduce the project size.
Articles in This Section
The information on this page is valid for UNIGINE 2.20 SDK.