Abstract
Realistic visualization of fire and smoke plays a crucial role in bridging the gap between computational simulations and intuitive understanding. In fields like fire safety engineering, emergency response training, and forensic analysis, visual fidelity can dramatically enhance both communication and decision-making. This article presents an overview of methods for importing and visualizing fire dynamics data—typically generated using PyroSim and the Fire Dynamics Simulator (FDS)—within Unreal Engine 5.
We outline two primary approaches to rendering volumetric fire and smoke based on simulation output:
- GPU-driven particle systems via Niagara, which can represent volumetric smoke using data-driven emitters
- volumetric raymarching using 3D textures, including support for Sparse Volume Textures and OpenVDB formats in UE5.3 and above
These techniques enable real-time, interactive exploration of smoke density, temperature fields, and flame emission from scientific datasets, allowing viewers to experience simulated fires from any viewpoint with physical accuracy.
By translating numerical voxel data—such as smoke concentration, temperature, and flow velocity—into immersive visual effects, we demonstrate how Unreal Engine can serve as both a high-performance rendering engine and a powerful scientific visualization tool. Whether the goal is maximum realism or interactive simulation review, this pipeline enables engineers and developers to present fire behavior in a form that is both informative and visually compelling.
Niagara vs Volumetric rendering
Each visualization method has its strengths and trade-offs
- The standard Niagara system is highly efficient, leveraging GPU compute to render large numbers of particles in real time. It offers precise control over particle positions, making it ideal for importing externally generated simulation data, such as voxelized smoke fields from FDS. Niagara also supports data-driven animation, enabling temporal playback of simulation states directly within a game / simulation environment. However, since each cell is represented by a discrete sprite or mesh, fine gradients and volumetric light interaction can be visually limited.
- Volumetric rendering using 3D textures or Sparse Volume Textures (SVT) offers higher fidelity, especially for continuous scalar fields like smoke density and temperature. With Unreal Engine built-in support for Heterogeneous Volume components and OpenVDB formats (support since UE 5.3), these volumes can be raymarched directly in the engine, offering soft transitions, light absorption, and physically accurate emission—ideal for scientific and cinematic purposes. The trade-off lies in higher GPU demands and a more complex data preparation pipeline.
Niagara-Based Visualization of Smoke and Fire (Particle Systems)
Niagara is Unreal Engine advanced particle system, designed for creating complex VFX with full GPU support. One of its key advantages is the ability to render large numbers of particles in real time.
Niagara is available in Unreal Engine through multile plugins:
- Niagara: Base Niagara effect systems
- NiagaraFluids: Fluid Simulation toolkit for Niagara
- NiagaraSimCaching: Support for recording and playing back Niagara simulations in sequencer
- Chaos Niagara: Tool to import desctruction data from Chaos into Niagara
As toolkits are use-case oriented, base Niagara system is an open system for diverse applications, supporting external data sources for data-driven particle visualizations.
Loading Scientific Data into Niagara
Fire simulation data typically includes fields such as smoke concentration, temperature, and flow velocity. These can be exported to CSV format and loaded into Niagara in one of two ways:
-
Using the HoudiniNiagara plugin
One approach is to convert FDS data (e.g., XYZ positions and smoke density values) into a format compatible with Niagara. The Houdini Engine toolkit includes a plugin that supports importing “Houdini CSV” (.hcsv) files as point caches directly into Niagara. These point caches predefine the locations and properties of particles.
To use this in your project, convert the simulation data to CSV format with columns for position (X, Y, Z) and a value such as smoke density. The Niagara emitter can then spawn particles at those positions and assign per-particle parameters based on the data—such as opacity mapped to smoke density.
-
Using C++ / Blueprints-Driven Data
- Read the CSV file in Blueprints and populate vector/float arrays.
- You can manually parse CSV files and pass arrays of positions and values into Niagara as user parameters using nodes like
Set Niagara Variable (Vec3 Array)
andSet Niagara Variable (Float Array)
- Inside the Niagara emitter, use the Particle Spawn script to:
- Spawn N particles (one for each data point)
- Assign positions from the position array (using Particle ID for indexing)
- Assign opacity or color based on the smoke density array.
Visualizing realistic Fire With Smoke
Each data point in the simulation grid can be represented by a single particle. Niagara emitters then use particle spawn scripts to place particles at the correct coordinates and assign them visual properties based on the input data.
-
Visualizing Smoke with Niagara
- Each particle should use a material that simulates a small puff of smoke, using either additive or translucent blending.
- A soft alpha mask (e.g., circular gradient or noise-based falloff) ensures smooth visual transitions and avoids harsh particle edges.
- The particle size should match or slightly exceed the simulation voxel size, ensuring a visually continuous smoke volume without visible gaps.
- Particles are rendered as billboards or sprites, typically with an
Unlit
shading model for consistent appearance regardless of scene lighting. - Smoke density values from the simulation are directly mapped to each particle’s opacity or color (e.g., higher density = darker or less transparent).
- You can conditionally skip emission for fully transparent particles (e.g., if density = 0), improving performance.
- All per-particle parameters (position, color, size, opacity) can be driven using Niagara’s spawn script with values imported from simulation data.
This setup creates an interactive, GPU-accelerated smoke effect that reacts in real-time as the viewer moves around the scene. With enough particles, the result visually approximates a volumetric cloud derived from simulation data.
-
Visualizing Fire with Niagara
For flame visualization, a second emitter can be added to the same Niagara System:
- Only spawn particles where the temperature exceeds a given threshold.
- Use additive materials with high emissive values to simulate the brightness of flames.
- Map temperature to color using a gradient (e.g., yellow → orange → red → white).
- Optionally, enable the Light module in Niagara to allow particles to emit dynamic light in the scene.
Particles can also be extended with ribbons or meshes to represent elongated flames, although sprites are often sufficient for high-performance rendering.
Combined Smoke and Fire in a Single Niagara System
A single Niagara System can include both smoke and fire emitters, ensuring synchronized playback. Because both are data-driven, their visual properties reflect the original simulation, allowing viewers to intuitively grasp the structure and dynamics of the fire event.
⏱ Time-Based Playback Support
Niagara system supports a time-dependent simulation, in other words, skipping in the simulation time. You can reach that functionality in following ways:
- Load a new dataset (e.g., CSV or user parameter array) for each time step.
- Deactivate and re-activate the Niagara System component each time step.
- This approach ensures fresh particles based on updated data but may cause visual popping.
- Ideal for offline rendering or frame-by-frame accurate playback.
- Keep one Niagara System instance active.
- At each time step, update user parameters (e.g., smoke density array, position array).
- Call
ResetSystem()
or re-activate the system to refresh particles with new data. - Ensures smoother runtime without constantly recreating components.
The time using the methods above can be controlled in any way either right from the simulation or through a User interface. There's also an option to use Houdini Point Cache
or precomputed flipbook-style cache if you work with external simulations.
Notes:
- Avoid interpolating scientific data unless it is specifically needed and justified.
- Always monitor performance: frequent respawning or large datasets may affect GPU budget.
- Use GPU particle pooling and Niagara scalability settings for optimal results.
Pros and Cons of the Niagara Approach
✅ Advantages | ❌ Limitations |
---|---|
Real-time performance (GPU compute) | Less accurate volumetric shading (compared to raymarching) |
Flexible data import from external simulations | Smoke may lack soft self-shadowing or volumetric light scattering |
Supports time-sequenced playback via Blueprint scripting | Requires manual material tuning and particle calibration |
Ideal for VR and interactive environments |
Niagara is ideal when performance and interactivity are the priority. It enables accurate spatial representation of simulation data and can be optimized to scale well in large or immersive scenes.
Volume Textures and Raymarching based visualization of Smoke and Fire
In addition to particle-based visualization, Unreal Engine 5 offers an alternative method to represent scientific fire and smoke data: rendering the simulation grid as a volumetric dataset. This method enables smooth, continuous visual effects, higher light fidelity, and emission behavior ideal for representing smoke and flames.
Volumetric rendering provides the most physically faithful visualization, ideal for cinematic sequences or high-fidelity scientific communication. UE5.3’s support for OpenVDB and Sparse Volume Textures makes it easier than ever to import real simulation data and visualize fire and smoke together in a fully raymarched environment.
Benefits of the Volumetric Approach:
Aspect | Advantage | Disadvantage |
---|---|---|
Visual Realism | Provides continuous, smooth volumes without visible particles. | May require tuning opacity and density mapping to match visual expectations. |
Light Interaction | Supports realistic absorption, scattering, and emission (e.g., smoke casting shadows, fire glowing). | Can be harder to integrate with non-volumetric lighting (e.g., shadowing from solid meshes). |
Scientific Accuracy | Directly maps FDS data (e.g., smoke density, temperature) to visual output. | Requires careful normalization and mapping of data channels. |
Support in UE5 | Native support via Sparse Volume Texture (SVT) and Heterogeneous Volume actor in UE5.3+. | Requires UE5.3+ for OpenVDB import; older versions need manual setup. |
Animation Support | SVT supports animation through frame sequences (.vdb), rendered in real time. | High memory usage if many frames are loaded simultaneously. |
Ease of Setup | Simplified when using SVT + Heterogeneous Volume (no shader scripting needed). | More complex if building your own raymarch shader manually. |
Performance (GPU Load) | Highly optimized SVT rendering for sparse data. | Raymarching is computationally heavy, especially for dense volumes or VR use. |
Performance (GPU Load) | Highly optimized SVT rendering for sparse data. | Raymarching is computationally heavy, especially for dense volumes or VR use. |
Integration with Fire | Allows combining smoke and flame in one volume (e.g., RGBA channels = density + temperature). | Requires careful balance between extinction (smoke opacity) and emission (fire glow) in material setup. |
Interaction / Interactivity | Viewer can explore the volume from any angle, with realistic volumetric lighting. | Less dynamic than particle systems (harder to add forces, wind, etc. in real time). |
Importing Volume Data
There are two main approaches to bring volumetric simulation data into UE5:
- Convert your FDS data to OpenVDB format using a Python script or data conversion tool.
- Import
.vdb
files into UE5.3+ as a Sparse Volume Texture (SVT) asset. - SVTs are highly memory efficient, ideal for sparse smoke fields.
- Use a Heterogeneous Volume actor to render the SVT directly, with full support for volumetric raymarching.
- Convert simulation slices into 2D images (e.g., PNG/TGA per Z-level).
- Import the set as a Volume Texture using the Texture Editor.
- Ensure textures are lossless (grayscale or HDR, with sRGB disabled).
Smoke & Fire visualization
-
Material Setup for Volumetric Smoke
- Create a material with Domain = Volume.
- Sample the imported 3D texture using the
Volume Texture Sample
node. - Feed the sampled density into:
- Extinction: controls how much light is absorbed (darker smoke = higher extinction).
- Albedo: defines the smoke color (usually gray or brownish).
- For advanced raymarching (without SVT), create a loop integrating density along the camera ray.
-
🔥 Volumetric Fire Visualization (Emission)
Flames can be visualized directly inside the same volume:
- Use the Blue or Red channel of the texture to store temperature or fuel concentration.
- Map these values to color using a Color Curve or LUT (e.g., blue → orange → yellow → white).
- Feed this into Emissive Color of the material.
- Optionally blend with Opacity for semi-transparent flame edges.
This simulates glowing, animated flames driven by temperature data.
Synchronizing Smoke and Fire
- For best results, use a single volume that stores both density and temperature.
- This avoids rendering overlap issues and ensures both effects react consistently to lighting.
- If using separate volumes for smoke and fire, beware of layering artifacts (UE5 does not yet handle multiple transparent volumes perfectly).
⏱ Time-Based Playback Support
Volumetric playback can be handled through either Sparse Volume Textures (SVT) or standard 3D Volume Textures.
- Import a sequence of
.vdb
files into UE5.3+ as a single SVT asset. - Use a Heterogeneous Volume Component in your scene.
- Enable animation playback via
bPlaying = true
and set the desiredFrameRate
. - For full control, expose the
Frame
variable and update it via Blueprint (e.g., slider).
- Prepare a set of preprocessed
VolumeTexture
assets (one per time step). - In Blueprint, dynamically update the texture parameter on your volumetric material using
SetTextureParameterValue
. - Store all frames in an array for indexed access.
- C++ only: create and update
UVolumeTexture
manually. - Could be paired with data streamed from disk or memory.
- This method requires more low-level programming and isn't generally recommended unless absolutely necessary.
Interpolation between frames
- If desired, interpolate between two textures using blend weight (e.g., linear interpolation between frame N and N+1).
- Best implemented in a custom volumetric material, but may introduce artifacts in scientific visualizations.
- Avoid loading all high-resolution frames at once if memory-constrained.
- Validate visible changes in smoke/fire to ensure that the time mapping is perceptually and scientifically accurate.
- UE5.3's SVT system is optimized for this kind of usage, with internal memory handling and efficient playback at ~24 FPS or more (depending on volume size).
Data verification
Before starting integration with Niagara or volumetric techniques, it's essential to verify the accuracy and spatial alignment of your simulation data. Even the most advanced rendering methods will fail to deliver meaningful results if the input data is not correctly prepared or interpreted.
This section outlines a practical workflow to bring data from PyroSim/FDS into Unreal Engine 5, enabling real-time visualization of fire and smoke over time. We assume you have simulation outputs available—such as .xyz
and .q
files (PLOT3D format)—and that you are able to convert them into a tabular CSV format. Each CSV file should include columns like X
, Y
, Z
, SmokeDensity
, and Temperature
for each simulation voxel, either as multiple per-frame files or a single file with time-indexed rows.
-
Preparing and Importing Simulation Data
Exporting from PyroSim/FDS
- Use PyroSim to export 3D simulation fields. If CSV export is not directly available, use a tool like Smokeview or a Python script to read
.xyz
and.q
files (PLOT3D format) and convert them to CSV. - Save each time frame as a separate file (e.g.,
sim_t001.csv
,sim_t002.csv
, etc.). - Verify that coordinates and units are consistent with Unreal’s default unit system (1 Unreal Unit = 1 centimeter).
- Use PyroSim to export 3D simulation fields. If CSV export is not directly available, use a tool like Smokeview or a Python script to read
Importing CSV into Unreal Engine 5
You have multiple options for handling CSV data inside UE5:
Data Table Import- First, define a Struct matching your CSV columns (e.g., floats for
X
,Y
,Z
,Smoke
,Temperature
). - Use the
Content Browser
>Import
to load the CSV and assign the struct. This creates a Data Table asset that can be accessed in Blueprints.
Runtime CSV Loading (Blueprint or C++)- Enable Editor Scripting Utilities, and use nodes like
Load File to String
to read the file into Blueprint. - Parse the content by lines and values
- For better performance and more control, use C++ via
FFileHelper::LoadFileToStringArray
and parse data withFCString::Atof
.
Houdini CSV (.hcsv)- If using the Houdini Niagara plugin, rename your CSV to
.hcsv
and import it as a Niagara Point Cache. - This provides direct access to the data inside Niagara's Timeline interface.
- First, define a Struct matching your CSV columns (e.g., floats for
In-Memory Data Structure
Once imported, ensure the data is available for iteration:
- In Blueprint, use
Get All Rows
on the Data Table to get an array of struct entries. - Store this array in a variable for reuse.
- If you have one file per time step, you can either:
- Preload all files into memory as a
Map<TimeStep, Array of Structs>
, or - Load only the current frame on demand (not ideal for timeline scrubbing—preloading a buffer of time steps is recommended if memory allows).
- Preload all files into memory as a
-
Smoke Visualization Debug Pass (Verifying Data Mapping)
Before moving to advanced visual effects, ensure that your data is correctly mapped spatially and visually:
-
Create a Debug Material
Create a simple Unlit material with a color parameter, or use an existing Emissive Unlit material that ignores lighting.
-
Spawn Instances in Space
- In Blueprint, loop through several (or all) voxels of a selected time step.
- Spawn a small Static Mesh (e.g., a sphere or cube) at each data point using either
Add StaticMeshComponent
or preferablyInstanced Static Mesh Component
for better performance. - Match the mesh scale to roughly one simulation cell.
- Assign the debug material and map smoke density to color or opacity.
-
Validate Positioning and Scale
- Enter Simulate or Play mode and freely navigate around the volume.
- Confirm that the cloud of instances visually aligns with the expected smoke structure.
- Fix any spatial inconsistencies:
- Axis orientation: Some simulators define the origin at a corner of the domain; shift or rotate the dataset if necessary.
- Scale: Ensure 1 unit in UE equals 1 cm or 1 m, as needed. Adjust during spawn logic if required.
-
-
🔥 Optional: Debug Visualization of Fire Data (e.g., Temperature, HRR)
In addition to smoke, you can also validate fire-related data—such as temperature or heat release rate (HRR)—using a similar instance-based debug visualization. This helps ensure that the fire fields are properly mapped and aligned in Unreal Engine before proceeding with emissive particles or volumetric emission.
-
Color-Coded Debug Visualization for Fire
- Use the same Instanced Static Mesh Component workflow as for smoke.
- Spawn instances at each voxel location.
- Instead of mapping SmokeDensity, use Temperature (or HRR) for color or emission intensity.
-
Example mapping:
- Blue = low temperature
- Orange = medium
- White = very high temperature
This gives you a visual sense of where flames should appear, how large or intense the fire zones are, and whether they align with your simulation expectations.
-
Validation in Context
- Once instances are visible in 3D space, simulate the scene and verify spatial coherence between smoke and fire regions.
- Are high-temperature voxels concentrated near the smoke source?
- Is there a consistent flame front forming where it should be?
This debug step is temporary but critical. It ensures that once you feed this data into Niagara or a custom shader, it will appear in the correct location with accurate dimensions. Once these checks are complete, you can confidently proceed to either the Niagara-based or volumetric visualization pipeline.
Optimizations
🧠 Performance Considerations
- Test performance on your target hardware setup (e.g., specific GPU or VR headset).
- Based on selected solution:
Niagara particle systems
GPU load can become high with hundreds of thousands of particles:
- Adjust particle size to reduce total count (larger sprites = fewer needed).
- Use distance-based culling or fade-out: Niagara can remove particles with low density or far from the camera.
volumetric raymarchingPay attention to step counts:
- Reduce sampling resolution (e.g., one step per 5–10 units instead of per unit).
- Heterogeneous Volume components expose parameters like
Step Size
for performance tuning. - Consider downsampling simulation data during export (e.g., use every second voxel) to reduce texture resolution.
Scientific Accuracy vs. Visual Readability
In scientific visualization, you usually aim for data fidelity, but small artistic touches can improve clarity:
- Add mild noise to smoke materials to simulate natural turbulence (optional toggle recommended).
- Slight color tinting (e.g., brownish hue) may help distinguish smoke types visually (e.g., soot vs. steam), though this may not reflect FDS accuracy.
Use transfer functions (e.g., linear or exponential opacity mapping) carefully to best represent real visibility behavior.
Data Validation
Always compare your output against reference frames from Smokeview or PyroSim:
- Check alignment of smoke volumes, flame fronts, and intensity at matching time steps.
- If discrepancies appear (e.g., wrong orientation, offset, inverted axes), revisit data preprocessing and coordinate mapping (see Step 2).
Visual validation helps catch issues like:
- Flipped coordinate axes (Z vs. Y),
- Inconsistent time indexing (frame mismatch),
- Incorrect unit conversion (meters vs. centimeters in UE5)
Advanced Notes, Pitfalls, and Best Practices for Fire & Smoke Visualization
Even after implementing the full visualization pipeline, it's important to account for edge cases and advanced topics that could significantly impact visual fidelity, performance, or scientific accuracy.
Handling Multi-Grid or Multiblock Simulations (FDS)
FDS simulations may consist of multiple spatial domains ("blocks"):
- Export Consideration: Each block must be exported separately unless merged beforehand.
- Unreal Integration:
- Unreal does not automatically tile or align multiple volumetric grids.
- Each block must be imported as a separate Niagara or Volume texture asset.
- Ensure proper positioning, scale, and orientation using transform settings.
- Tip: Use naming conventions like block_01.vdb, block_02.vdb and associate them with metadata (grid origin, scale).
- Risk: Mismatch at seams, overlapping data, or axis inversion if grids aren't carefully aligned.
Timeline Playback Challenges and Synchronization
When building a time-driven visualization:
- Skip or Interpolate?
- For missing time steps: either interpolate (visually smooth, less accurate) or skip (preserves scientific fidelity).
- Prefer skipping for fire safety or research usage.
- Looping Animation:
- Add logic to detect last frame and restart (loop), pause, or reset.
- Optional UI toggle for loop mode.
- Delta-Time Sync:
- Frame skipping may occur if deltaTime fluctuates.
- Recommended: fix FPS or use tick-based update (e.g., update every 0.1s).
Scene Integration (for VR or Training Environments)
To make your fire/smoke effect feel like part of the world:
- Lighting Consistency:
- Use dynamic lights from fire particles only if needed (limit count).
- Volumetric fire materials should emit light; use emissive output for glow
- For smoke, test "Receive Volumetric Translucency" and shadowing with directional lights.
- Interaction Design:
- Plan interactions (e.g., visibility drop in smoke, damage zones near fire)
- Optionally add collisions around fire zones to trigger responses.
- VR Consideration:
- Volumetric effects are GPU-intensive in VR. Use LODs or disable detailed FX for distant zones.
Debugging the Visualization Pipeline
Common issues and how to resolve them:
- Invisible Smoke:
- Check data range: if smoke density is near 0, particles may have 0 alpha.
- Try clamping values or remapping 0–1.
- SVT Not Playing:
- Make sure
bPlaying
is checked and FrameRate is set. - Expose Frame property and update it manually to verify playback.
- Make sure
- No Visual Output at All:
- Temporarily boost emissive strength (e.g., ×10) or change color to bright red.
- Check if your material domain is set correctly (Volume, Surface, etc.).
Dynamic / Real-Time Simulation Data (Advanced Use Case)
If you want to stream simulation results live (e.g., during training):
- Input Methods:
- Use sockets or HTTP/UDP from external app (e.g., FDS running live).
- Parse in C++ and pass data to Niagara or Volume Textures.
- Write a custom Data Interface for real-time point injection.
- Volume Texture Option:
- Unreal doesn't support runtime creation of Volume Textures in Blueprints.
- Use C++ to generate UVolumeTexture or update RT textures.
⚠️ This is highly advanced and not required for static playback workflows.
Visual Fidelity vs Resolution (Perceptual Quality)
Sometimes visual quality isn't linear with data resolution:
- Downsampling:
Use every 2nd or 3rd voxel to reduce texture size — surprisingly acceptable with good shading.
- Visual Grid Test:
- Render voxel size using overlay grid (e.g., debug lines or mesh overlay).
- Use this to test alignment, scale, and perceived smoothness.
Export Settings for FDS / PyroSim
To ensure smooth Unreal import, configure export carefully:
- Sampling Rate:
- Spatial: Choose a voxel size small enough to resolve smoke structure (e.g., 0.1 m or finer).
- Temporal: Choose export timestep matching visual update frequency (e.g., 0.1s for 10 FPS playback).
- Fields to Export:
- Prefer
SMOKE DENSITY
orVISIBILITY
for smoke. - For fire: use
TEMPERATURE
orHRR
(heat release rate). - Combine multiple fields into one CSV/VDB when possible (RGBA = density + temperature).
- Prefer
- Units:
- Convert to cm if targeting UE default scale (1uu = 1 cm).
- Align origin (corner vs center of domain) to avoid spatial offset.