This page describes the various steps required to integrate PopcornFX in your game engine.
You can find an overview of PopcornFX here: https://www.popcornfx.com/docs/popcornfx-v2/popcornfx-overview/
Before integrating the SDK, it is recommended to think about the desired pipeline for effects creation and import to make sure the PopcornFX project(s) are correctly set up for your production(s):
- Have a PopcornFX project for each production, or share it across all titles?
- Set up versioning for source effects
- Set up project properties
- Coordinate system (handedness, up axis…)
- File formats supported by your game engine
- Decide where to place the PopcornFX project (directly in the game’s content directory or in an external location)
Effects import and play in game engine
PopcornFX SDK core modules handle effects simulation in your game engine. In order to load an effect in your game engine, it must first be baked.
Baking compiles the effect with additional optimizations and saves them in an efficient runtime-ready binary format. Three options are available to bake effects:
- Using the in-editor bake (there are some limitations)
- Using the default effect baker (binary shipped with the SDK)
- Using the asset baker library
You can use our default effects “baker” by baking effects from PopcornFX Editor. This bakes both the effect and its resources (textures / meshes / ..). It can be customized by adding custom baking command lines to bake the effect dependencies into asset formats supported by your game engine.
For a better integration in your level editor / game engine editor, you can integrate the “asset baker library” and trigger baking directly from your level editor (no need to have PopcornFX Editor opened to bake / import an effect).
Once effects are baked, they can be loaded in your game engine. Loading an effect is done using the specified “file system”. We provide default file systems for easier / faster integration, but it is possible to override it so PopcornFX effects are loaded using the engine’s loading / file system.
As effects can have external resource dependencies (textures /vector fields / ..) used at runtime, it is also possible to override default “resource handlers” so that effects may use game engine custom file formats directly.
Now that effects are loaded, they can be instantiated in your level(s). Default implementations are provided for core components required by PopcornFX SDK:
- Thread pool (task system)
- Memory allocations
- Assertion system
It is however common for studios to override these default implementations to better fit with specificities of the game engine.
PopcornFX supports various “renderers”, you can decide which one would be most suitable to your game engine as per your need: https://www.popcornfx.com/docs/popcornfx-v2/rendering/.
Default (sample) rendering integration
For a fast integration, we provide a sample library that relies on our graphics abstraction (RHI).
It currently supports Vulkan, D3D11, D3D12, OpenGL, Metal, PS4’s and PS5’s rendering APIs. Draw calls are emitted by those libs and shaders / resources are handled internally so you don’t have any control on those. That sample library supports the same rendering features as PopcornFX Editor.
However, we do not recommend to integrate PopcornFX rendering this way for several reasons:
- It is impossible to use game engine shaders on PopcornFX particles
- Sorting between PopcornFX particles and other game engine objects (ie. transparent) will be impossible / complicated
- Upgrades with future SDK versions can be painful as it’s likely you’ll have to modify that sample code to fit your needs
- You have no control on what’s happening / how particles are rendered
This approach is only relevant as an implementation example for all the code-samples which do rendering and to simply get something up and running in a timely manner. Ultimately, this should be replaced by a proper full rendering integration.
Custom (full) rendering integration
For a better integration, we provide a “render helpers” library, that handles all PopcornFX specific data for rendering (preparing everything you need to issue your draw calls) and provides entry points for game engine render code.
This rendering integration approach takes more time but is highly recommended. Doing so will allow you to:
- Have a full control of how PopcornFX particles are rendered
- Use your own resources (and rendering resources manager) for particle rendering (materials / shaders, meshes, textures, ..)
- Correctly sort PopcornFX draw calls and other game engines’ ones, in the relevant render passes.
- Support any custom feature of your game engine that we do not support in the samples library (cascaded shadow maps, motion blur, custom lighting, post processes, ..)
- Override the default geometry generation method (CPU billboarding) with other custom methods (vertex shaders, compute shaders, geometry shaders, tessellation shaders..).
High-level engine interactions
Correctly importing, updating and rendering effects is key, but there are also high level integration features that might be implemented. Here are some examples:
- Emitter component (emitter transforms, UI to start / stop / pause emitters)
- Emitter attributes (customize game engine editor UI, and expose gameplay bindings to set / get them)
- Emitter attribute samplers (customize game engine editor UI, and expose gameplay bindings)
- Game engine “scene interface”:
- Implement PopcornFX particle collisions with game engine world
- Handle “broadcasted events” (ie. if a particle collides with a wall, spawn a decal or a sound)
- Hot-reload PopcornFX effects if the source has been modified (live-link equivalent)