Optimising FPS in an Unreal engine based Digital Twin simulation
Digital Twin simulations provide a critical interface for understanding, analysing, and interacting with real-world systems virtually. But, ensuring these simulations run smoothly requires careful attention to performance, particularly frame-per-second (FPS) optimization. Unreal Engine offers a robust set of tools and methods to optimize FPS. This guide dives deeper into practical methods and strategies for improving performance in such simulations. (do feel free to try out but always keep a copy of your project if you are changing project settings — or push your changes to main and do the changes in a different branch if you are using version control)
One more thing, if you’re building a Digital Twin with Unreal Engine, you may have chosen it because of all the inbuilt features that makes life easier. Remeber your Digital Twin must function before all the visualisations (so choose your priorities wisely ;) )
Look into what causes bottlenecks
The first step in optimization is to understand what is causing low FPS.
Use Unreal Engine Profiler:
- Open the Profiler through
Window > Developer Tools > Session Frontend
. - Analyze CPU, GPU, and memory usage in real-time to identify spikes or performance issues.
Stat Commands:
- Use commands like
stat unit
to view frame time for CPU and GPU andstat fps
for real-time FPS feedback. stat scenerendering
helps identify rendering inefficiencies such as overdraw.
GPU Visualizer:
- Press
Ctrl+Shift+Comma
in Play mode to bring up the GPU Visualizer. This shows GPU-related performance issues like heavy materials or shadowing
Too many traingles?
Look into your Geometry and Level Design. fficient level design is crucial for reducing computational overhead.
Implement Level of Detail (LOD):
- Open the Static Mesh Editor for assets, and under
Details
, configure LOD settings. - Use Unreal’s built-in LOD generator (
LOD Auto Generation
) to simplify meshes based on distance.
Culling:
- Enable Distance Culling via the
Cull Distance Volume
actor in the level to specify cull distances for objects. - Use Occlusion Culling by enabling it in
Project Settings > Rendering > Occlusion Culling
.
Mesh Instancing:
- Use Hierarchical Instanced Static Mesh Components to batch similar meshes into a single draw call. Add instances via Blueprints or code.
Too many shaders to compile?
Simplify materials and textures in your level. Complex materials and oversized textures are a common performance drain.
Reduce Material Complexity:
- Open the Material Editor and check the complexity using the Shader Complexity View (
Lit > Optimization View Modes > Shader Complexity
). - Replace dynamic calculations with static/precomputed values (e.g., baked normal maps).
Compress and Resize Textures:
- Open textures in the Texture Editor and use
Mip Gen Settings
to ensure Unreal auto-generates mipmaps for scaling. - Adjust resolution via
Max In-Game Size
to reduce the load on the GPU.
Texture Packing:
- Combine maps like roughness, metallic, and ambient occlusion into a single texture using channels (R, G, B, A). Tools like Photoshop or Substance Painter can aid this process.
Lights Lights!
Lighting and shadows are computationally expensive, especially in large-scale Digital Twin environments.
Static Lighting:
- Use Static Lights for non-dynamic objects. Bake lighting into lightmaps using
Build > Lighting Only
in the editor.
Shadow Adjustments:
- Reduce shadow resolution via the Directional Light Settings (
Shadow Resolution Scale
) and limit shadow cascades usingNum Dynamic Shadow Cascades
. - Disable shadows for small, non-critical objects by unchecking
Cast Shadows
in their properties.
Reflection Optimization:
- Replace dynamic reflections with Box Reflection Capture and Sphere Reflection Capture actors.
Your code/blueprint
Blueprints and scripts can be a hidden source of performance issues.
Event-Driven Programming:
- Replace
Tick
functions with custom events or timers where possible to avoid per-frame execution. - Use the Event Driven Loader to load only essential assets at runtime.
Code Profiling:
- Use
Unreal Insights
to profile custom logic, pinpoint slow functions, and optimize scripts. - Avoid deep, nested loops and heavy runtime calculations.
Adjust Engine Scalability and Render Settings
Fine-tuning Unreal Engine’s scalability and render settings can have a significant impact.
Scalability Settings:
- Adjust under
Settings > Engine Scalability Settings
. Prioritize reducing View Distance, Shadows, and Effects quality.
Dynamic Resolution:
- Enable Dynamic Resolution in
Project Settings > Engine > Rendering
. Unreal will dynamically adjust the screen resolution to maintain target FPS.
Frame Rate Capping:
- Set frame rate limits in
Project Settings > General Settings > Framerate
. A stable cap prevents unnecessary GPU load.
Multithreading and Async Processing
Digital Twins often require processing large datasets, making it essential to utilize multithreading.
Asynchronous Asset Loading:
- Use Async Loading Screen plugin to load heavy assets without freezing gameplay.
Physics Threading:
- Enable
Use Multiple Threads for Physics
inProject Settings > Physics
to offload collision calculations.
Test on Target Hardware
Simulated performance on a high-end development machine often doesn’t match the real-world hardware used for deployment.
Unreal Insights:
- Use this tool to measure performance on target devices, accessible under
Window > Developer Tools > Unreal Insights
.
Hardware Benchmarks:
- Test across various GPUs and CPUs using third-party benchmarks to align performance settings with hardware capabilities.