Fluid Flux is a comprehensive solution for simulating realistic water surfaces and fluid interactions within Unreal Engine. This documentation outlines its core features, tools, and best practices to help users achieve optimal results.

A foundational understanding of the Unreal Editor, Blueprint visual scripting, and content management is beneficial when working with the system. Following the outlined procedures will ensure a streamlined workflow and effective implementation across various project types.

Installation

Fluid Flux can be purchased on the Fab marketplace and installed using the FAB plugin.

Frequent updates for Fluid Flux are planned, so always ensure you use the newest product version. The latest version of the product is outlined on the Unreal marketplace page and at the beginning of the documentation.

Following the installation/update procedure ensures a smooth transition and minimizes the risk of potential issues arising during the update process.


List of plugins required by Fluid Flux:

  • UE Fab Plugin (installation)
  • PythonScriptPlugin, (editor tools)
  • EditotScriptingUtilities, (editor tools)
  • GeometryScripting, (mesh generator)
  • PoceduralMeshComponent, 
  • Niagara,

In the final stage of configuring the project, make sure that project settings are properly configurated:

DBuffer

Enabled

It’s required for proper decal (wetness and caustics) rendering. If you don’t want to use those effects, you can disable decal material in the surface actor.
CustomDepth-Stencil Pass Enabled This feature is required for the rendering of underwater depth maps.

MaskMaterials only in early Z-pass

False

Required for proper tunnel capturing.
Velocity Pass  Write During Base Pass This feature improves the motion vector rendering.
Default Renderer Motion Vector Precise This feature improves the motion vector rendering.
MaskMaterials only in early Z-pass False Required for proper tunnel capturing.
Strta/Substrate Disabled Requires a patch to work. Detailed description in

Substrate compatibility

Make sure that Real-time rendering is active in your viewport, which is required to simulate fluid in the editor.

Substrate compatibility

The Substrate is Unreal Engine 5’s advanced material authoring framework, replacing the fixed suite of shading models and blend modes, such as Default Lit and Clear Coat, with a more expressive and modular system. Substrate is still experimental (unstable), and many developers may not support it yet.

The Fluid Flux update 3.0.3 introduces Substrate support in UE5.4 and UE5.5. However, the pack is developed by default using the standard material system. Substrate translators do not fully convert Fluid Flux materials into the new system, requiring additional patched material files to ensure compatibility.

In the case of Fluid Flux, there are no noticeable visual improvements or benefits from switching to the Substrate system. As a result, the entire process aims to maintain compatibility across all projects.

  1. Enable substrate in your project.
  2. Download the patched materials pack.
  3. Unzip files and notice that the hierarchy of files fits the Fluid Flux structure.
  4. Copy the whole hierarchy FluidFlux folder to the Content folder in your project. Accept replacing files.

Project structure

The Fluid Flux project is organized in a certain way. This short description will bring you closer to what kind of content can be found in each folder. Before starting work with the pack, it’s worth familiarizing yourself with its structure and the systems it provides. 

  • Demo –  The demo is the most important folder for new users. The demo examples present how to use this pack, achieve effects, and integrate systems with characters. Everything that can’t be found in this documentation will be shown in demo files. Files in the Demo folder are not linked by the product and can be removed from the project at any time to optimize the build/project size.
  • Editor – editor-related tools, icons, utilities, procedural mesh generator
  • Simulation – Shallow water simulation actor and tools for controlling fluids and generating state.
  • Coastline – Generating coastline data for oceans.
  • Interaction – A simple system of interactions that adds detailed lightweight ripple fluid simulations.
  • Surface –  Renders surface, underwater volume, post-process, caustics, and playing audio.
  • Tools – Multiple tools that are shared between systems for generating heightmaps, SDF, and procedural meshes.
  • Environment – Niagara particle systems that allow readback information from simulation implementing swimming, buoyancy, and drive particles using fluid state.
  • Waves is a system designed to generate ocean waves that can be used in the background and mixed with fluid simulation.

Reporting Bugs

This Support and Reporting Bugs guide provides essential guidance on reporting system errors. Learn how to identify, report, and analyze bugs to ensure smooth support.

Player character

The demo maps showcase the features of Fluid Flux with the help of example classes like BP_DemoCharacter, which provide a fully functional implementation of the character interacting with water. The Fluid Flux build for UE 5.3+ uses Enhanced Input, which implements character input inside the project.

Character-related implementation is simplified to a minimum and encapsulated in separate classes, which makes transferring the implementation even simpler. This document does not provide a detailed step-by-step description of implementing character but highlights the components and features used. More detailed descriptions can be found in the sections dedicated to these tools:

FluxDataComponent Used for extracting surface information (velocity, height, and volume) from the water system. Provides that to other systems.
FluxInteractionComponent It generates waves after interaction on the water surface.
FluxByounacyComponent Character floating on water. Activates only when the character switches to a ragdoll state.
FluxSwimmingComponent Implements swimming movement. It changes the state of character when it’s in water and can swim (not ragdoll).  
FluxDriverComponent Implements the communication between vehicle and character that allows possessing.
FluxModifierForceComponent Simulation modifier that moves water around character only inside of domain area.

The easiest way to investigate how components are used in the character is to click the right mouse button on Component -> “find references,” the engine will show you all the places where it is implemented.

Disabling help panel

After running the demo, you can notice the help panel located in the bottom right corner of the screen, which is helpful for testing features in the maps. The panel is added automatically. If you use an example character in your project and want to remove this hud, there are many ways to choose:

  1. Add ToggleVisible in “begin play” FluidFluxPlayerController like this:image.png
  1. Remove the “Create BP_HudWidged” node in the player controller
  2. Switch the game mode (controller) in your level from the demo to your game controller. 

Swimming component

In general, swimming is not a prominent feature of this product; it is more of an additional example that presents one of many ways to do it. The swimming example is shown in DemoCharacter and requires a few things to work.

  1. Swimming requires PhysicsVolume on the map with PhysicsVolume.Water Volume=true is used to activate swimming when the character is inside.
  2. The swimming system requires Character.BP_FluxDataComponent that provides data from water.
  3. The BP_FluxSwimmingComponent implements movement for you and controls CharacterMovement, which is required.
  4. Open and click the right mouse button on BP_FluxSwimming -> “find references,” and you will see how it is controlled using input.
  5. The swimming animation depends on the character animation blueprint implementation and will vary in every project, so there are many ways to implement it. My simple example switches animation when  SwimmingState is detected in SwimmingComponent.

Vehicle driver

The Fluid Flux has a unique vehicle pawn actor that can be possessed and controlled. The actor BP_FluxBuoyancyVehiclePawn is a template of the vehicle that can be inherited and implemented depending on requirements.

The vehicle system supports many valuable features:

  • Smooth physics replication with quantization
  • Smooth camera movement with adjustment to direction
  • Jump force action
  • Enhanced input
  • Customizable movement
  • Interaction trails
  • Possessing by closest character (attaching player)

An example of the use of vehicle class is implemented in the BP_FluxBoatPawn actor placed on demo maps.  

Motorboat properties that users can adjust.

The movement of the motorboat vehicle is implemented in the function UpdateSteering, which converts the input to the motor force applied to the virtual location of a propeller in the water. All the input is replicated, and the system also implements a custom synchronization of the vehicle’s physical body.

The possessing system requires adding BP_FluxDriverComponent to the player pawn. This class is used for binding OnInteractionEvent, executed when the input is activated. This simple class acts as a bridge between the vehicle and the driver.


Buoyancy component

The buoyancy is an upward force exerted by a fluid that opposes the weight of a partially or fully immersed object. The BP_FluxByouancyComponent calculates physical forces based on the configuration set using a PDA_FluxBuoyancyData data asset. Additionally, the system supports drag and current force that uses fluid velocity to determine movement.

Multiple byouancy copomonents can share the same Data Assets. The Data asset can be also switched dynamically based on requrements (for example destroyed ship that is drowning can use another data asset).

Example use cases of the buoyancy system can be found in the demo actors:

  • BP_FluxCrate – a most straightforward actor with one pontoon.
  • BP_FluxBoatPawn – a combination of multiple portions attached to the static mesh.
  • BP_DemoCharacter – ragdoll is made of pontoons attached to skeletal mesh.

Limitations:

  • The buoyancy forces require a physical body, which means it can’t be used in a sequencer that does not simulate rigid body physics in the editor.
  • Only spherical pontoons are supported, and this approximation is not precise, especially for hard-edged meshes.
  • The system requires FluxDataComponent to read the surface height and velocity weight.

Adding buoyancy system to actor:

  1. Add BP_FluxByouancyComponent to the actor.
  2. Add BP_FluxDataComponent to actor – this will be responsible for reading water height.
  3. Create a new DataAsset that will store buoyancy settings. You can copy/use examples. DA_BuoyancyBoat, DA_BuoyancyCrate, DA_BuoyancyRagdoll or create a new one. ContentBrowswer->Right button->Miscelleneus->DataAsset->PDA_FluxBuoyancyData.
  4. Set newly created data asset in your actor component:  BP_FluxBuoyancyComponent.DataAsset
  5. Set ComponentTag = “FluxBuoyancyOwner” in the actor component (mesh) that should be used as a parent of Buoyancy transformations.

The actor is already configured, but you must edit FluxBuoyancyData and adjust the parameters. You can do it with the help of the EUW_FluxBuoyancyEditor tool described below.

 Using FluxBuoyancyEditor Editor

FluxBuoyancyEditor is an Editor Utility Tool created to preview and edit buoyancy settings in a 3d viewport.

  1. Open the folder /Game/FluidFlux/Editor/Widgets/  in the content browser
  2. Click the Right button on ethe ditor utility EUW_FluxBuoyancyEditor and choose RunEditorUtilityWidged
  3. Select the actor class with configurated Buoyancy system. Example boat.
  4. Now, you can edit the settings of the data asset in the right panel; when work is done, click SaveAsset.

Editor controls:

  • Mouse Left button – selecting buoyancy pontoon (switching to pontoon settings)
  • No selection – shows global parameters
  • Mouse  Right button drag – camera rotation
  • Mouse scroll – camera distance change

The buoyancy geometry is represented as a list of spherical pontoons that approximate the shape of the body. Every pontoon has parameters that should be customized for specific use cases:

Parameter Description
Socket Name of bone or socket used for attaching the pontoon.
Radius The radius of the pontoon sphere.
Offset Offset relative to Socket or parent component.
DensityWeight Scale of the density (larger density means heavier object and less buoyant)
DragWeight The scale of the drag effect (how fluid movement mushes the pontoon)

You can run the game and edit buoyancy setting in runtime, everything will be update and you will see the changes in your game.

Good practices and solving problems:

  • If the boat is flipping, then adjust the center of mass Z location (set it to a lower value so it will behave stable)
  • Try to fit the pontoons to the geometry of the mesh. It is more precise when detecting water and behaves more predictably.
  • Adjust side drag to stop boats from sliding sideways.
  • Edit FluxBuoyancyEditor and game in runtime mode.
  • Make sure the physical body has Tag seto to FluxBuoyancyOwner
  • Use the DrawDebug option to visualize pontoons in runtime.
  • Attribute BP_FluxByouancyComponent UsePontoonsInFluxData forces Flux data to generate custom readback points for every pontoon it is precise but also may be slow in case of many pontoons.

Surface actor

The BP_FluxSurface actor is an abstract class generalizing an audiovisual representation of the simulation and coastline domain data. By default, this actor can’t be placed on the level as it is only an abstract class designed as a template that should be configured. 

An abstract actor is like a guide for creating new actors. It defines some common features that all related classes should have, but it’s not complete on its own. Other classes need to finish the details. For example, an abstract class may not specify any ambient water audio, but a customized ocean template has sounds that match the type of water it represents.

The surface actor implements a list of advanced subsystems:

Actor component   Features 
DecalCausticsWet
  • caustics decal
  • surface wetness decal
SurfaceOverMesh
  • surface mesh
  • surface scattering
  • surface foam
  • surface detail advection
Post-Process
  • underwater postprocess
  • underwater  waterline
SurfaceUnderMesh
  • underwater surface
SurfaceProceduralMesh
  • Generating procedural static mesh
FluxAudioComponent
  • Analyzing fluid surface for audio source
Volume Absorption, Volume Scattering
  • Rendering underwater fog and absorption volume

The BP_FluxSurface is an abstract base parent class, meaning it can’t be placed directly on a level. Configuring all these subsystems can be time-consuming, particularly for new users. This is why the package includes basic configured surface child actors templates that can be found in the FluidFlux/Surface/Templates folder.

 Template  Description

BP_FluxSurface_Water

Default water surface spawned dynamically when the domain.SurfaceActorReference is not specified.

BP_FluxSurface_River

Simple river/waterfall material and basic underwater post-process, reiver audio

BP_FluxSurface_Ocean

Advanced ocean materials, ocean audio, materials blended with wave actor, underwater mesh, underwater scattering, and absorption volume.

BP_FluxSurface_Coastline

Rendering two domains simulation and coastline at the same time.

Users can also implement their surface templates and extend the surface’s functionalities.

Surface actor does not have any data to render, meaning simulation or coastline domains have to send it to the actor by setting the SurfaceActorReference. The SurfaceActorReference attribute in the Domain actor you use (SimulationDomain or CoastlineDomain) should reference the surface actor that will render the data. Otherwise, the domain will spawn a temporary water surface that can’t be configured by hand.


Interaction system

The BP_FluxInteractionCapture is designed to add efficient, detailed interaction simulated in small areas around the camera (or specified object).

  • It is a perfect addition that can improve the look of baked simulation almost for free.
  • It currently supports the most straightforward fast ripple solver, but there are plans to simulate a fluid pressure solver in the future.

The interaction system configuration is demonstrated in many example blueprints in the Fluid Flux demo: BP_DemoCharacterBP_FluxBoatand BP_FluxCrate.

A detailed explanation of the implementation presented in BP_DemoCharacter can be found below:

  1. Component.BP_FluxDataComponent – This component reads the fluid data needed during further interaction calculations, such as height and velocity. You can find more information about this component and configuration in the section Async readback.
  2. Component.BP_FluxInteractionComponentThis component stores a list of interaction sources. The interaction source is a sphere attached to the component (or skeletal mesh bone) that generates waves after interacting with fluid.
    Configuration of interaction surface attached to l_foot bone. The system uses owner skeletal component with the tag “FluxInteractionOwner”.
  3. Interaction sources will be attached to mesh (skeletal or static) with the tag specified in the OwnerComponentTag attribute. Hence, adding this tag (FluxInteractionOwner) to the skeletal mesh that will move the interaction sources is essential.

  4. The BPI_FluxInteraction interface handles communication between the actor and the interaction capture system. It should be added to the Class Settings of the actor that will interact.
    Player character interfaces
  5. Implement the GetInteractions in BPI_FluxInteraction. When BP_FluxInteractionCapture is an overlapping interactive actor, it calls this GetInteractions function to find information about occurring interactions. 
    Simple implementation of the GetInteractions function from the BPI_FluxInteraction interface.
  6. The BP_FluxInteractionCapture actor is placed on every map. The actor detects the interactable actors and manages the whole process of generating the interaction effect. The InteractionCapture actor uses the overlap to find actors inside the interaction actor area. This mechanism ensures that only the area’s actors are considered potential interaction sources. For example, a character uses the Capsule component for overlap; custom actors require adding a collision component like SphereCollision.

There are many steps to do before interaction start working but no worries you can debug and make sure that every part of your implementation works correctly:
1. Test it on demo maps at first
2. Enable DrawDebug in BP_FluxInteractionCapture
3. Enable DebugDraw in BP_FluxDataComponent  
4. Enable DebugDraw in BP_FluxInteractionComponent
5. Make sure that “GetInteractions” is evaluated. Put a breakpoint in this function to check. If its not then your actor is not detected by overlap with InteractionCapture and you may have to add collision volume to your actor.

Interactions with a fluid surface may generate splashes, which add realism and immersion to the simulation. This is achieved through a straightforward mechanism that detects when the interaction source intersects the fluid surface. If this condition is met, a splash effect is created to simulate the disturbance caused by the interaction.

Communication between interaction component and surface actor.

The InteractionComponent->Source->SplashType defines the splash index stored in the Surface->InteractionSplashes array.


Color presets

The color preset system is a powerful tool for effortlessly configuring the visual aspects of water. It offers a range of predefined presets, eliminating the need to create new material instances to modify scattering and absorption.

Before starting to change the color of the water, make sure the surface is configured correctly. The SurfaceActorReference attribute in the Domain actor you use (SimulationDomain or CoastlineDomain) should reference your surface actor. Otherwise, the domain will spawn a temporary water surface that can’t be configured by hand.

Changing surface color:

  1. Select the surface actor on your map.
  2. Find MeshRendering Tab and attributes: BaseColorPreset
  3. You can use any preset from my list of predefined colors or create a duplicate and modify it.

Creating new custom color preset data asset:

Many pre-configured color presets are available for oceans, shallow water, and rivers. Additionally, users can create their water presets by duplicating existing examples and adjusting the parameters as desired, allowing for seamless customization and experimentation.

  1. In the content browser, open folder /FluidFlux/Content/FluidFlux/Surface/Templates/Color/
  2. Find a data asset preset closest to the effect you want to achieve. 
  3. Duplicate chosen data asset
  4. Set the data asset to the surface rendered on your map (attribute BaseColorPreset)
  5. Open data assets and edit parameters:

World painter and brush

The FluxWorldBrush is a unique actor designed to manipulate data stored in the WorldPainterComponent canvas. The system offers three distinct types of canvas on which the FluxWorldBrush can perform painting operations:

  • ColorPainter ( BP_FluxWorldPainter), interpolation between the base color and painter color.
  • WaveSize (BP_FluxCoastlineDomain), interpolation between no wave and highest wave.
  • WaveType (BP_FluxWorldDomain), interpolation between Oceanic wave and coastline wave

This two-minute tutorial presents the workflow and possibilities of brushes:


Reading fluid data

The Fluid Flux uses Niagara asynchronous readback events to read data from fluid render targets and pass them to blueprints. The BP_FluxDataComponent listener can receive, update, and store fluid data at a specific location.

The Fluid Flux uses this feature in multiple situations:

  • buoyancy and floating objects
  • automatic dam breaking 
  • interaction detection
  • swimming system
  • fluid sound source analyzer
  • underwater camera detection

Add BP_FluxDataComponent to your actor, and it will automatically detect the fluid surface under the actor. BP_FluxRotatorActor is an excellent example of an actor that can react to fluid.

The Readback data component can be attached to the scene component in the owner actor by adding the tag “FluxReadbackOwner.”

The Flux Data component attached to the skeletal mesh will follow the ragdoll.

Use Debug option in FluxDataComponent to make sure that component is following your actor and sampling proper values. 


Niagara integration

The Niagara integration is based on three elements:

  1. BP_FluxNiagaraActor communicates with the simulation and data to the Niagara system.
  2. NE_FluxData emitter should be inherited by the Niagara system to read the data.
  3. NMS_FluxData is a special module that extracts simulation data from Stage Transients variables that can be used to drive the particles.

All particle systems (trash, plants, splashes) in the pack are constructed similarly; feel free to check and modify the examples.


Translucency

Rendering underwater translucents is, in general, a challenging problem to solve. Single-layer water materials do not support translucency, so translucents are invisible when watching surfaces from above water.

In general, I recommend using dithering instead of translucency.

The underwater volume post-process implementation is more functional because it can be overlayed with translucent meshes. It means translucent mesh is rendered on top of postprocess volume, but developers must handle the fading.

Example translucent mesh fading implementation.

Final effect:


Cut mask and holes

In general, the system supports two methods of cutting holes in the water surface.

The first method is a bit tricky and designed for small boats. Look at the example boat mesh (Demo/Environment/Boat/SM_Boat) that uses additional cap mesh with M_FluxSurfaceInvisible material. The M_FluxSurfaceInvisible renders translucent material using the Single Layer Water mode that overrides the water surface and makes it invisible.

The second method for cutting holes requires the BP_SurfaceCutMask actor, which defines the rectangular area that will be removed. Unfortunately, only one cut mask per surface actor is supported right now.

  1. Drag and drop the BP_SurfaceCutMask actor into an area where water should be cuted out.
  2. Select the BP_FluxSurface actor on your level and set the newly created actor to the CutMaskActor attribute.
    Example cut mask implementation presented on the FluxBeachMap.

Domain actors

Ground capture

Ground capture is a key component of Fluid Flux systems, ensuring that fluids interact correctly with the environment by requiring a defined container or boundary. This is achieved by detecting water blockers using a top-down projection of the scene, which generates a height map. The height map, also called a ground map, is a specialized texture where each pixel represents the height of the underlying geometry. This process enables precise identification of fluid boundaries and supports realistic interactions with complex terrain.

In the Fluid Flux pack, this task is handled by FluxHeightmapComponent, which is used in both the simulation and coastline domains. The generated height data play a pivotal role in determining the appearance and movement of water on slopes.


Visibility options

The ground scene capture component renders the current scene into a heightmap texture. Sometimes, we must exclude certain actors, such as bridges, that should not act as fluid blockers. In the ‘Domain:Heightmap: CaptureVisibility‘ tab, you can find options that may help determine which meshes should be visible in the heightmap:

VisibilityMode can be used to determine whether the capture actor should render the entire scene and exclude specified actors (HideAllListed) or build a list of actors that should be used as blockers (ShowOnlyListed).”

  • ActorsReferences – exclude chosen actor objects on your scene
  • Actos of Class – can be used for excluding by type of actor class and its child classes
  • ActorsWithTag = “FluxHide“: Every actor that uses this tag will be added to the list of excluded objects.
  • Use the M_PhantomMesh material to render the mesh ONLY during processing the ground capture  (which is invisible to the world). This technique is good for imitating soft slopes of waterfalls or creating an alternative version of the ground when the environment is more complicated (like indoor meshes). 

Solving issues

If something is not rendering properly in the height map, you can investigate what is happening without simulating the fluid. The debug preview option is the most crucial feature for domain actors. It shows a height map that will block the water on the scene in case of problems, bugs, or unexpected behavior.

There are many ways to configure the debug preview:

 Domain DebugAttribute  Description

DebugHiddenInGame

Debugging will only be visible in the editor. You can turn it off to see how the ground map is generated in runtime (sometimes, there may be a difference, for example, when the map is loading for a long time and the ground map captures the LOD details).

DebugPreview

Enable/Disable debug mesh.

DebugSelectedOnly

Allows to preview the debug only when the domain is selected.
Debug preview. Notice colored horizontal lines coating the geometry of the environment.

It’s noticeable that not every detail will be captured on the ground map, and the accuracy depends on the grid scale (attribute AreaWorldPixelSize). The shader for rendering this preview colors lines based on slope and exposes the ground’s discontinuity. 

Visualization  Description

Green lines

Easy to simulate, very stable fluid.

Blue lines

It has a good slope for moving fluid in some direction.

Red lines

The area may cause instability if fluid flows on it, but it is suitable for walls.

White lines

There may be some caves that can expose holes in the fluid mesh. 

Fully red polygons

represent holes and discontinuity in the mesh. It should be eliminated if fluid can flow into this area.

Landscape or mesh is not rendering to the ground map

If the “PixelDepthOffset” feature is used in the material, it may not be rendered to a ground map and cause some simulation problems. This problem can be easily fixed in your material by simple modification. Use the MF_FluxPixelDepthOffset material node to disable “PixelDepthOffset” while rendering the ground map.

The M_Photoscan_Master material is an example of a workaround for this problem using the MF_FluxPixelDepthOffset node.

Wrong Domain Z location:

Remember that after adding the Domain actor to your map, you must modify the domain actor’s height (Z position) depending on your landscape. The debug grid on top of the landscape geometry indicates everything works fine.

Groundmap works in the editor, but it is broken in the build or runtime.

There is a slight difference between testing in PIE and running the Shipping/Development build. Understanding this issue is crucial for finding a solution. The editor uses assets that are already loaded and can render them immediately. However, when you run the executable, the system has to stream landscape and meshes. When the Fluid Flux system captures the ground map and the scene has not yet been streamed, it may lead to inaccuracies, such as a flat ground map or the use of lower LOD. There are several potential solutions:

  1. Increasing the SimulationDomain.RuntimeCaptureDelay – delay is the simplest way to determine if this is the issue in your case. If, after increasing the value, the ground is captured correctly, it indicates that the ground was not ready when captured initially. However, this is not the optimal solution because you cannot predict how fast the game will load on various target devices. Low-end PCs and consoles may load more slowly, potentially resulting in unpredictable behavior.
  2. OnLevelLoaded events – The most effective approach is to use SimulationDomain.RuntimeCaptureDelay = -1 and execute the function  SimulationDomain.BeginPlaySimulation by hand from an event that notifies you when the level is loaded and ready for use. Unfortunately, there are no such events in the blueprint, so you will need to track this on your own in C++.”
  3. Setting SimulationDomain.UseInitialStateGround=true forces the system to utilize the ground map from the data stored in the exported SimulationDomain.InitialState

Simulation Domain

The Fluid Flux simulation implementation is based on shallow water equations. The shallow water equations are a set of mathematical equations that describe water flow in shallow areas, such as rivers and streams. They are commonly used in hydrodynamic modeling to simulate the movement of water and predict its behavior under various conditions. The resulting simulation will show the movement of the water and the formation of ripples and waves on the surface. You can adjust the initial conditions and parameters of the simulation to see how they affect the movement of the water and the formation of ripples. Remember that the shallow water equations are a simplified water flow model, and they may not always accurately reflect the behavior of actual water. 

The BP_FluxSimulationDomain blueprint is the heart of the Fluid Flux system. This blueprint is responsible for handling important tasks like:

  • Generating the ground height map to the texture (using FluxHeightmapComponent)
  • Updating simulation of shallow water fluid, foam, and wetness.
  • Baking and exporting simulation state.
  • Sending data to the fluid surface renderer.

The Shallow Water simulation is based on assuming linear vertical pressure profiles, so it is simulated in two dimensions. In general, the algorithm can be described in a few steps: 

  1. Simulation data is stored on 2D render targets.
    Ground map – information about landscape and obstacles
    Velocity (RG) Depth(B) Foam(A) map – stores information about fluid
    Height(R) Wetness(G)  map – stores surface height and wetness of the surface
  2. The slope of the ground heightfield and the slope of fluid are combined and used to calculate the pressure and velocity.
  3. Simulation is an interactive process of updating fluid height and velocity.
  4. The result of integration is used for foam and velocity advection.
  5. Fluid modifiers are used as input for simulation to change the current state.
  6. The simulation frame accumulates fluid wetness and generates the fluid surface mesh displacement.

     

The BP_FluxSimulationDomain actor placed on the map is doing nothing because it’s empty and needs to be filled with fluid. The simplest way to fill containers with fluid is by using a Modifier source actor.


The BP_FluxSimulationDomain blueprint has a straightforward editor that simulates the fluid’s state on the map in the editor mode. Simulation can be prepared in the editor baked to state or dynamically updated by the simulation blueprint.


Modifier Component

A modifier component is a powerful tool that affects the simulation state and changes the current simulation state. It’s the simplest way to interact with the simulation. Modifiers can be used for:

  • Adding/removing fluid in the simulation domain.
  • Changing the velocity and flow direction of the fluid
  • Simulating custom interaction with fluid
  • Generating waves

The tutorial below presents how to add a source modifier on the scene and fill the simulation domain with fluid:

The Fluid Flux contains predefined modifiers:

  • BP_FluxModifierComponent – Base parent class for all fluid modifiers. Every modifier component extends it and implements specific behavior. Users can create custom modifier classes and materials for specific use cases like whirlpools/waves. Describing the architecture is outside of the scope of documentation. The BP_FluxModifierSourceComponent component is an excellent example of a modifier that can be used as a starting point for learning how the system is designed.
  • BP_FluxModifierSourceComponent – Simple modifier that allows adding/removing fluid and changing velocity in a specific area. 
    Parameters  
    Volume The quantity of fluid applied by modifier (depending on Mode).
    Velocity The velocity of fluid applied by the modifier (depending on Mode).
    Shape The shape of the fluid modifier
    Mode Defines how the modifier is applied to the simulation. All modifiers are rendered to a simulation buffer. Mode is a method of blending used during this process.
    Add – This mode will add the ‘volume’ of fluid and its velocity to the current fluid on the map.
    Adjust – adjusting the current state of fluid to the height of the modifier.
    Set – will set the constant height of fluid in the area.
    Edge The softness/hardness of the modifier edge. Useful for soft mixing with fluid or uniform filling the vessel.
    Intensity Scale the modifier’s effect on the domain (0.0, 1.0>.
    Duration Defines how long the fluid source will be active. (less than 0 means infinite), (0 Rendered in a single frame and then modifier will be disabled), (more than 0 is the duration in seconds)
    SortPriority Affecting an order of modifiers in the queue. It may be helpful when the user needs to fill the domain and then remove some fluid. A value larger than 1000 forces the system to add on the end without sorting.
    AutoActivate The modifier can be inactive initially and activated by an event from gameplay or a sequencer.

    There are many ways to remove fluid in the simulation domain. It depends on the mode you choose:
    Mode= Set,      Volume=0               – will set 0 water in the area of the modifier
    Mode= Adjust,  Actor.Z position     – lock fluid at a specific height
    Mode= Add,      Volume negative   – slowly removes fluid

  • BP_FluxModifierGerstnerComponent – Generates waves/fluid on borders of the simulation domain. More info and use cases can be found in the chapters related to ocean configuration.
  • BP_FluxModifierForceComponent – Generates forces when the actor moves (based on the velocity). It can be added to the character.

Modifier Container

The modifier container is a particular type of actor that can store multiple modifiers and send them to the simulation. If the actor implements the BPI_FluxModifierContainer interface, it’s considered a modifier container.

BPI_FluxModifierContainer interface can be implemented by any actor. A good example is BP_DemoCharacter that uses BP_FluxModifierForceComponent to interact with a fluid. AddModiffiers function only needs to be implemented to make it work.

BP_FluxModifierContainerActor is a primary container that can combine multiple modifier components in a single actor that works simultaneously.

BP_FluxModifierSourceActor is a specific type of container actor that simplifies the process of adding simple source modifiers to the scene.

Every modifier is rendered in an additional render target pass, so it’s not cheap. Minimizing the number of fluid modifiers inside the simulation is good practice to achieve the highest performance.

Solving issues

Unexpected spikes sometimes destroy the simulation. Shallow water simulation can exhibit unpredictable behavior due to the loss of stability when encountering steep slopes. This is a widely recognized problem that can be resolved by fine-tuning specific parameters and enhancing the reliability of the simulation.

Simulation spikes are caused by the instability of simulation in some conditions.
  • Slope Scale (Increase)
    Increasing this parameter will scale the scene’s height on the Z-axis and make your fluid move slower on slopes. (This parameter will probably be redesigned in the future version for better consistency with the world scale measurements).
  • OvershootineBlend(increase), OvershootingEdge(Decrease) Fixes overshooting problem bysmootcheening 
  • Simulation Delta Time (Decrease)
    Fluid flux is updating with constant delay time. That means the time that elapsed between two game frames is divided by delta time, and the result is the number of iterations. In general, more iterations mean less performance. By default, the Simulation Delta Time attribute is set to 0.2. It is not safe in terms of accuracy, but it can work with the highest performance.
  • Debug Preview / Debug Hidden In-Game (Debug)
    Pay attention to the ground debug preview. If you spot some red spikes where the simulation does not work correctly, your ground texture and geometry should probably be adjusted.
  • Tweak other variables like slope clamp, velocity clamp, friction, damping, gravity, and even world pixel scale can make a difference.

I am still experimenting with different solutions for this spikes problem and trying to figure out some method to force stability even in bad conditions. You can expect multiple improvements in future updates.


Fluid state

The PDA_FluxSimulationState is a unique data asset created especially for storing the current frame of the simulation. The simulation state is the most essential structure in the system.

The simulation actor dynamically updates simulation states. A dynamic simulation state is automatically created in the constructor script and stored in BP_FluxSimulationDomain.CurrentState actor. Data can be easily previewed and used for rendering and further fluid analysis.

The simulation state can be exported to the data asset and used later in many ways.

  • It can be loaded in runtime
  • It can be used as a starting point for the simulation
  • It can send data to render by surface actor
  • It can be used in other gameplay tools in Niagara emitters and materials

Exporting State

BP_FluxSimulationDomain.CurrentState can be baked to an asset by clicking the right button on  BP_FluxSimulationDomain and choosing Scripted Actions -> Flux Export Simulation. The short tutorial below presents the process of generating and exporting the fluid state to a data asset:

  1. (0:07) Prepare data assets that will store the state  
  2. (0:20) Start the simulation of fluid on your map and stop when it’s ready
  3. (0:50) Choose SimulationDomain->ContextMenu->ScriptedActions->FluxExportSimulation 
  4. (0.54) Select the newly created state as a target and adjust settings.


     Parameter

     Description

    ExportHeightMax ExportVelocityMax

    ExportHeightMax and ExportVelocityMax can improve quality. When the velocity or height in the exported simulation is very small, it is worth scaling the precision to use the whole range of bytes when storing the data. The exporter should do this automatically when opening the script. However, analyzing the entire simulation may require many computations and additional implementation, so I decided to leave it for manual adjustments.

    UseCompression Exporting compressed assets. It can save some memory but also affects the quality of the surface.
    Level Of Detail Scales down the simulation resolution
    Apply State to Surface Applies exported data to the surface, which allows previewing the results.

After those actions, you should see the generated state and additional textures.

Example river state and baked textures.

Pay attention to simulation resolution! The “Power of Two” rule is a fundamental necessity due to the way game engines work. You will not be able to export simulation state if it is size is not power of two (128/256/512/1024 etc.)

 

 

Use case 1: Initial state

Using the state as the initial state of simulation allows to start the simulation from a specific frame. It means that a simulation of flowing water does not have to be generated every time the game starts it can start from the saved frame.

  1. Select SimulationDomain
  2. Find InisialState attribute
  3. Set the state exported before

Since now, the simulation has started by reading data from the state.


Use case 2: Loading state in gameplay

Sometimes, there is a need to load state during the gameplay in blueprints like a checkpoint. Simulation->LoadInitialState function can be used to handle these tasks. Example use presented in the screenshot below:

River State loaded 10s after beginning play of the level.

Use case 3: Using state without simulation

If you are not planning to update the simulation dynamically, then a better option is to remove or disable the SimulationDomain actor and use SimulationState directly in the FluxSurface. This solution may be way faster and more reliable and save some memory. Use this configuration:

  1. Configure SimulationDomain and run the simulation.
  2. Click the right mouse button on SimulationDomian and export it to the state data asset.
  3. Set SimulationDomain->AffectWorld = false
  4. Set Surface->SimulationState directly using the exported asset.

BP_FluxSimulationDomain.SurfaceActorReference is set, actors communicate together, and the state is automatically passed to BP_FluxSurface.SimulationState, but changing the AffectWorld=false disables this connection. 

SimulationDomain can be removed or set IsEditorOnlyActor to avoid spawning it in the final build and wasting memory.


Dynamic ground

The Fluid Flux uses a static ground map for simulating fluids, but occasionally updating is allowed. It is costly, so it is not recommended to use this operation in every frame:

The BP_BreakableDam presented in the video can be destroyed when the player hits the trigger. It is an excellent example of updating the ground after the dynamic object. Look at the Break function, which is the heart of the dam system.

It evaluates UpdatGroundMap on a simulation actor, which takes the object’s position and size that will disappear to recreate the ground in this area. You can do the same operation when adding something on your level.


Mesh generator

The static mesh mode is the most efficient way to render fluid flux water surfaces. In Fluid Flux 3.0, the mesh generator was rewritten to a new separate editor actor tool called BP_FluxSurfaceMeshGenerator.

The new tool uses the Geometry Scriprs Plugin introduced in Unreal Engine 5, so don’t forget to enable it in your projects!  

Features of the mesh generator:

  • This new tool is now separated from the BP_FluxSurface actor, making the interface cleaner and more encapsulated.
  • The new wireframe preview option dramatically improves the visualization of exported meshes.
  • Baker optimizes mesh density using fast built-in engine geometry scripts, so geometry density is better distributed.
  • Performance issues related to reading render targets were addressed, and the whole generation process is working over 50 times faster.
  • The new static mesh generator provides more precise results and supports bigger meshes, thanks to shortening generation time.
  • Exporting is simplified as the target mesh can be pinned to the blueprint and overridden every time it changes.

The video below presents the optimized output mesh generated in the editor with wireframe preview enabled that can be found in the Demo/FluxRiverStaticMap:

Unfortunately, there are still some limitations:

  • Unfortunately, there are still some limitations:
  • Geometry Scriprs works only in the editor, so generating static meshes in runtime is no longer supported.
  • Generating huge meshes may take some time as the system is implemented partially in blueprints.
  • The generator works only for rivers and lakes. Building static mesh for the ocean does make sense, as it should be dynamic.
  •  The output mesh can’t be blended with the ocean because it uses another surface rendering mode.
  • If the mesh is too dense, generation may not execute as it may exceed the available iteration count in blueprints. It can be fixed by increasing the maximum loop iteration count parameter in project settings.

Generator tabs:

All generator attributes are organized in separate tabs designed for specific tasks:

  • Exporter – saving data and configuration of target mesh that will be exported, file name generation, etc.
  • Source – Source of data for generation. The system can read data from the Simulation Domain, Surface Actor, or Simulation Data Asset.
  • Generator – Parameters for processing mesh generation and mesh simplification.
  • Preview – The way how the mesh is displayed to the user. Preview mode is crucial:
    PreviewEditor_GeneratedMesh – generated preview of mesh that can be adjusted.
    PreviewActor_DataAsset – original data asset rendering.
    PreviewActor_StaticMesh – final generated mesh on surface.

Generating mesh

In the tutorial below, we will go through a workflow for generating static meshes based on the baked state of the simulation.

  1. Use simulation domain to generate water. (previous chapters)
  2. Export simulated state to Simulation Data Asset (previous chapters)
  3. Switch surface to static mode (SimulationDomain.AfectWorld=false, SurfaceActor->SimulationState=Exported state.
  4. Add BP_FluxSurfaceMeshGenerator on level.
  5. Set the SurfaceMeshGenerator.SourceActor = Level.Surface (it provides data for generation) 
    Alternatively, you can set the SourceDataAsset = exported data asset.
  6. Set the SurfaceMeshGenerator.PreviewActor = Level.Surface (it will display the data)
  7. Set previewMode = PreviewEditor_GeneratorMesh. This option will render the mesh generated directly in the editor. It can’t be used in runtime.
  8. Use Exporter options to Target Static Mesh or generate a new one when it’s undefined.
  9. Click “Save to Mesh Asset” to export the mesh.
  10. When SurfaceMeshGenerator.TargetStaticMesh is set; you can switch the preview option to PreviewActor_StaticMesh to see the exported mesh in the game. 

The BP_FluxSurface actor renders static meshes using the special mode SurfaceMeshMode=Domain_GeneratedMesh, which is automatically set by the generator.

 The example preview material “MI_River_SurfaceOverStatic” is designed for static meshes and can handle fluid data such as foam and velocity encoded in vertex color. The material is set to do mode  Material.UseSimulation = false, which means the system will read the data from the vertex information instead of sampling textures.

Surface PreviewActor_StaticMesh uses SurfaceOvewBakedMaterial for rendering geometry. 


Recreating Ocean

Creating an ocean scene is an advanced topic involving coordinating multiple actors simultaneously. It is good to try all other tutorials before starting to work on recreating the ocean scene. Examples of ocean setup are presented in the demo maps FluxIslandMap and FluxBeachMap. You can copy this setup (SurfaceActor, SimulationDomain, WaveTexture, WaveModifier) or create it from scratch on your map using the description from this chapter:

Configuration step by step:

  1. Start with an empty map with some island/landscape/ground meshed.
  2. Add actors:
    • Add BP_FluxSimulationDomain actor. Responsible for simulating water.
    • Add BP_FluxSurface_Ocean actor. Responsible for rendering.
    • Add BP_FluxOceanWave actor. Responsible for ocean waves outside the simulation.
    • Add BP_FluxModifierWaveActor actor. Responsible for generating waves in simulation.
  3. Select BP_FluxSurface_Ocean actor
    • Set Surface->SurfaceMeshMode = InfiniteGrid_128_Niagara. It will force rendering infinite mesh (a feature added in version 2.0).
    • Set Surface->OceanWaveActor = FluxOceanWave. This action will facilitate the reading of data from the ocean wave actor.
  4. Select BP_FluxOceanWave – the dedicated actor that provides ocean waves. Implementation is much simpler than the classical analytical approaches like Gertner or FFT. The system uses animated 3D texture (VT_OceanWave) generated in a blender.
    • Adjust the Z position of the ocean wave actor.
    • Adjust wavelength and wave height to your needs.
  5. Select BP_FluxModifierWaveActor actor
    • Adjust the transform of ModifierWave to cover the edges of the simulation that should generate waves. Change position and size if needed.
  6. Select BP_FluxSimulationDomain actor 
    • Switch the simulation domain surface to force rendering a new surface
      Simulation->SuraceActorReference = BP_FluxSurface_Ocean
    • Change the blending of the simulation with the waves outside the simulation using the Simulation->Domain->AreaWorldBlend=(0.1, 0.1, 0.1, 0.1). You can adjust it to your needs. Custom blending between oceanic waves outside the simulation may be necessary in special cases, such as when dealing with a one-sided ocean. This can be achieved by configuring the AreaWorldBlend attribute within the SimulationDomain actor.
    • Adjust the Z position of the simulation actor.
    • Adjust the XY location, resolution, WorldPixelSize, and size to cover the area where the shallow water simulation should be generated.
    • Ensure the ground map is captured correctly by checking if the debug grid represents your scene. (For more info, check the ground capture-related chapters)
  7. Test the simulation. Click SimulationDomain->StartSimulation or run the game.

Sequencer

Sequencer allows users to create in-game cinematics through its specialized multi-track editor.  Unreal Engine has many options that can be used for previewing scenes, but Fluid Flux does not support some of them:

  1. Real-time – You can preview the simulation by hitting “play” (green button) in the editor. It will show you how it would behave in real-time.
  2. Editor – Clicking “Start Simulation” in BP_FluxSimulation actor on the scene (as presented in tutorials) allows you to generate some specific frame and sawing int to state (an initial state that can be pinned to the simulation actor as the first frame).
  3. Sequencer editor – Simulation can’t be previewed in the sequencer because the Fluid Flux system does not allow rewinding simulation in the current version, and the sequencer affects actors – the topic is very complicated.
  4. Capture Movie – Sequencer Render Movie to Video. It works as in real-time mode, and Fluid Flux water will render correctly in the final video.
  5. Capture 360 – This option was never tested.

If you want to preview the simulation with a sequencer, then this setup may be helpful for you:

  1. Drag and drop the sequencer on your map.
  2. Switch the AutoPlay option in LevelSequenceActor.
  3. Press “Play in selected viewport” or “Simulate.”

Fluid Flux provides an option to use modifier activation/deactivation functions from a sequencer. The process of using this functionality is simple:

  1. Add Sequencer on the level and set parameter: Autoplay=True
  2. Add Source modifier on the level and set parameters Duration=-1, AutoActivate=false
  3. Drag and drop the Source modifier to the sequencer.
  4. Add Track->FluxModifierSource
  5. Choose the moment of activation on the timeline and click “Add a new key,” then change the event’s properties as presented on the screen below. You can choose the Activate/Deactivate function.

Now, you can test the scene by rendering a video or playing the game. The modifier should activate automatically by sequencer event.


Coastline Domain

The BP_FluxCoastlineDomain is a dedicated system designed specifically for capturing and baking world data into CoastlineState. The architecture of the BP_FluxCoastlineDomain system is similar to the BP_FluxSimulationDomain, ensuring consistency and familiarity. 

The coastline state serves as a fundamental data source during the rendering process for coastlines and oceans. The BP_FluxCoastlineDomain can communicate with the FluxSurface actor and feed it with data needed to render the water as presented in the short video tutorial below:

Coastline state

The BP_FluxCoastlineDomain actor generates a state that can be exported and saved as the data asset and stored in the project files. The CoastlineState data asset can be used as an initial state in the BP_FluxCoastlineDomain actor or loaded directly in the BP_FluxSurfaceActor, the same way as in the case of the SimulationState.

Exporting the current coastline state can be described in a few simple steps:

  1. Create an empty coastline data asset to store the data.
    ContentBrowswer->RightMouseButton->Miscellaneus->DataAsset->PDA_FluxCoastlineState
  2. Save to newly created data assets.
    Select CoastlineDomain->RightMouseButton->ScriptedAction>FluxExportCoastline


Exported CoastlineState data asset stores two textures.

  • WorldGroundMap stores the height map of the coastline area.
  • WorldCoastlineMap stores the distance to the coastline, direction, wave height, and blending of the coastline.

If you are not planning to update the coastline dynamically, then maybe a better option would be removing (or disabling) the CoastlineDomain actor and using CoastlineState directly in the Surface actor. It may be way faster, more reliable, and save some memory.

Try this configuration:

  1. Configure CoastlineDomain and export it to the state.
  2. Set CoastlineDomain->AffectWorld = false
  3. Set CoastlineDomain->IsEditorOnlyActor = true
  4. Set Surface->CoastlinerState directly using the exported asset.

You don’t have to remove the domain actor from the scene because IsEditorOnlyActor will remove it automatically for you in final build. Thanks to this solution you are able to use it later again in the editor for regenerating the state if the level geometry change.

Solving Issues

If, after following the tutorial steps, the coastline does not appear, you have likely encountered one of the scenarios listed below:

  1. Z location of the Coastline actor is wrong:

    Remember that after adding the BP_FluxCoastlineDomain actor on your map, you need to modify the domain actor’s height (Z position) depending on your landscape. Otherwise, you may not be able to see coastline waves.

    The debug grid on top of the landscape geometry indicates everything works fine.

  2. Landscape material uses Pixel Depth Offset:

    If the “PixelDepthOffset” feature is used in the material, it may not be rendered to a ground map and cause some simulation problems. This problem can be easily fixed in your material by simple modification.

    Use the MF_FluxPixelDepthOffset material node to disable “PixelDepthOffset” while caching the ground map.

    The M_Photoscan_Master material is an example of a workaround for this problem using the MF_FluxPixelDepthOffset node.

  3. The coastline is incorrect in standalone/shipping or looks different after play
    This issue is associated with the landscape not being ready during the map loading process, and the system utilizes a lower Level of Detail (LOD) for rendering the ground. Detailed explanations can be found in “Groundmap solving issues: Groundmap is broken in shipping/development build.” Two potential solutions are available:
    – Use the RuntimeCaptureDelay attribute to postpone rendering the height map, 
    – Save the coastline to the state and directly load it from the data asset.

Glass system

The glass rendering system in Fluid Flux 3.0 is built upon three interdependent systems integrated with the BP_FluxSurface actor. Each of these systems will be described in detail later in this chapter:

  1. Masking
    The geometry of the glass volume is captured into an SDF (Signed Distance Field), which is then used to cut holes in the surface mesh.

  2. Glass
    The BP_FluxGlassActor can render any mesh as glass while sampling water height to apply advanced post-process effects like waterline refraction and absorption.

    • You can use multiple glass actors simultaneously.
    • Note: Calculating water-related data is computationally intensive and processed per vertex. To ensure optimal results, glass meshes must have a high vertex density and use multiple layers of transparency.
  3. Absorption
    The volume mesh absorbs light within the underwater distance field to create realistic underwater scenes enhanced by watercolor-inspired lighting effects. The effect is implemented in Surface.VolumeAbsorptionMaterial automatically applies the colors of the water based on the geometry inside the SDF attached to the surface. Clearing out this material disables the effect.

Example use cases of glass systems are presented on demonstration maps and can be found in the Demo/Maps folder:

  • FluxGlassSectionMap – Only the glass system is used to render the borders of the simulation. The old fluid cross-section system was removed from the surface actor. This map uses a custom glass actor BP_FluxGlassSection (example on FluxSectionMap) to achieve the effect of the water volume cut.
  • FluxOceanMap – The simplest example of an SDF domain and a sphere of glass cutting a hole in the ocean. 
  • FluxCoastlineMap– Single SDF domain capturing the spline mesh tunnel and rendering glass combined with the coastline.
  • FluxIslandMap – Advanced example presenting a mix of multiple types of SDF bodies and glass meshes (spline, Box, Sphere) and simulation reacting on glass mesh.
  • UseCase_02_InverseTube– Inversed spline mesh glass and inversed sdf cut. Additionally, the configuration presents the top cap of the ground map used as a blocker for fluid inside the tube (see the ground map after selecting Simulation Domain)

Example configuration:

  1. Prepare map with water and configured surface actor
  2. Drag and drop the glass actor BP_FluxGlassBox on the level.
  3. Drag and drop BP_SDFVolumeDomain on the level.
  4. Adjust its location, resolution, and texel size to cover the area where glass mesh should cut the hole.
  5. Add created Map.BP_FluxGlassBox to BP_SDFVolumeDomain.SourceActors. The domain will read the shape data from this actor.
  6. Add created Map.BP_SurfaceActor to BP_SDFVolumeDomain.TargetActors. Domain will send generated SDF to this actor.

Masking surface

A Signed Distance Field (SDF) volume is a 3D representation where each point in space stores the shortest distance to the surface of a shape. The “signed” aspect means the distance is positive outside the shape and negative inside, allowing precise surface representation. Fluid Flux uses a signed distance field volume (BP_SDFVolumeDomain) to represent shapes that can cut holes in the water mesh surface. Sampling data from the SDF volume can determine if a point on the surface is inside or outside the shape.

Capturing shapes:

Building an SDF volume requires capturing the distance to the surface of the scene geometry. This process requires a specifying list of actors that will be captured by adding them to the array BP_SDFVolumeDomain.SourceActors are array. Those sources of data can be generated differently depending on the type of geometry, and Fluid Flux supports a few basing types of SDF sources (implementing the BPI_SDFSource):

  • BP_SDFShape – The most straightforward mesh shape represents a box with round corners.
  • BP_SDFOutline – Intermediate actor capturing data from Spline actor meshes that can capture many spline meshes simultaneously.
  • BP_SDFProjection – capture scene geometry to heightmap and then convert to SDF (Experimental)
  • BP_FluxGlassBox/BP_FluxGlassSphere – custom implementations of glass actors integrated with BP_SDFShape.

Sending data to actors:

The BP_SDFVolumeDomain is the only container that generates and stores information about the signed distance field. Those data need to be sent to other actors for further use. The list of actors that should receive data from Domain is defined in BP_SDFVolumeDomain->TargetActors.

Example systems that use the SDF data,

  • BP_SDFPreview(implements BPI_SDFRenderer) simple actor can be used to debug the SDF on the plane mesh.
  • BP_FluxSurface(attribute SignedDistanceFieldMask), the surface actor, uses those data to cut holes and lender volumes.

Exporting SDF to data asset:

Overall, the system is built to generate SDFs in real time. However, an additional feature is the ability to save a baked SDF volume as a data asset (PDA_FluxSignedDistanceField). This enables the SDF to be stored statically on disk, bypassing the resource-intensive process of runtime generation. The export method is similar to that used for other data assets in Fluid Flux.

  1. Crate PDA_FluxSignedDistanceField data asset.
  2. Select BP_SDFVolumeDomain
  3. Click the right button on it and choose Scriptat Actor Actions -> SignedDistanceField->Export.

The exported PDA_FluxSignedDistanceField asset can be used directly in the Surface actor as BP_FluxSurface->SignedDistanceFieldMask. Remember to disable generation of the BP_SDFVolumeDomain by using the attribute AffectWorld=false  or removing the Domain.

Limitations:

  • SDF Domain Coverage – The SDF (Signed Distance Field) domain must cover the entire tunnel area, represented as a 3D texture. Stretching the SDF across a large scale can significantly increase memory usage. I intend to address this limitation by implementing virtual texturing in a future update.
  • Spline Mesh to SDF Workflow – Baking spline meshes to the SDF is slow and involves multiple steps, which can confuse new users. I aim to streamline this process by transitioning the implementation to Niagara, making it more efficient and user-friendly.
  • Surface Hole Cutting Precision Cutting holes in the surface using the SDF can occasionally appear imprecise. While increasing the SDF resolution can resolve these issues, it may also lead to excessive memory consumption, surpassing practical budgets.

Glass rendering

A glass rendering system is an advanced combination of materials that uses advanced translucency rendering in Unreal Engine.

The system is based on BP_FluxGlassActor, which implements a few based functionalities and attributes shared between numerous predefined types of glass actors that can be placed on a map:

  • BP_FluxGlassBox
  • BP_FluxGlassSphere
  • BP_FluxGlassSection
  • BP_FluxGlassSphere

The glass is rendered as multiple instances of the same mesh interpreted differently depending on the material it uses. Those material layers can be adjusted in glass actors:

  • Absorption/Scattering – is responsible for rendering the volume of water behind glass. The mesh uses data from the Fluid Flux surface to calculate depth and cut off the mesh in areas where water volume should not be displayed. It is rendered as two independent translucent passes, multiplicative absorption, and additive scattering. The scattering layer also supports the refraction effect of the waterline and water drops.
  • Glass Inside – material used for rendering dirty glass and prebaked cube map refraction.
  • Glass outside – this layer renders the dithered glass material visible outside the tunnel. It uses dithered transparency, making it a bit smearing but improving performance, fixing bugs related to invisible glass under single-layer water surfaces, and translucency sorting. This mesh is also used to render soft shadows.
  • Simulation Phantom – this mesh is used to cut off the area from the simulation ground map.

What’s New?

More effects, better performance! Is it even possible?

It’s been over a year since the last major update to Fluid Flux, and while I often call updates ‘big,’ this one truly stands out. The update 3.0 is massive, bringing significant improvements in performance, stability, and memory management, along with many new features and enhancements. So much has been added during development that I might struggle to list every improvement here—I honestly lost track somewhere along the way while adding all kinds of exciting new functionality!

Demo

The new demo is already available on itchio.com. During the development, most of the focus was on improving maps and extending functionalities.

  • The Island level received a crucial update with an underwater tunnel example.
  • The beach map was changed to more rainy and foggy conditions to present new particle system integration and how Fluid Flux works in different weather conditions.
  • The coastline map will work much faster now as performance has dramatically improved with new rendering optimizations.
  • The ocean map was extended by the Large World Coordinate test and dynamic wind. 
  • SectionMap uses a new glass system instead of building in section mesh.

If you’re enjoying Fluid Flux, appreciate the update, and want to see more improvements like this in the future, I’d be grateful if you could leave a review. If you haven’t tried Fluid Flux yet, you can purchase it on FAB.

Before updating your project

The new version only applies to Unreal Engine 5.3+ and higher, and there will not be any updates for the older engine versions.

All levels were updated, performance improved, and quality and reliability improved. Due to this update’s extensive scope, certain aspects might have been overlooked during the development and testing phases. To ensure a smooth transition, it is strongly recommended that you make a copy of your project before downloading the update.

Please read the detailed Package Update/Installation Process.

Underwater glass

The biggest and most spectacular feature of this product is the glass system. Example presentations generated millions of views on my X, and I believe many users will find even better, more spectacular use cases than mine.

The glass system is built on three cooperating mechanisms integrated with BP_FluxSurface actor:

  1. Masking surface – The geometry of the glass volume is captured to SDF (signed distance field), and then the result is used to cut holes in the surface mesh.
  2. Filling holes with glass – BP_FluxGlassActor can render any mesh as glass and sample water height to apply post-process effects like waterline refraction and absorption. You can use as many glass actors as you need, but be aware that calculating data about water requires heavy computations calculated per vertex. Glass meshes need to be quite dense to work correctly and also use multiple layers of transly1
  3. Lighting in the tunnel – The volume mesh absorbs the light inside the tunnel to simulate underwater scenes lightened by watercolor.

Glass system still has many limitations:

  • The whole Tunnel area should be covered by the SDF domain, which is 3d texture and may require a lot of memory when stretched on a large scale. I plan to address this limitation by implementing Virtual texturing in the future.
  • Glass mesh can receive shadows. It’s translucent, so it’s mostly not noticeable, but it still sometimes may break the visual appearance.
  • Baking spline mesh to SDF is slow and requires many additional steps, confusing new users. I plan to improve it by moving the whole implementation to Niagara.
  • Cutting holes in the surface using the SDF may sometimes look imprecise; increasing resolution can fix those bugs but also exceed memory budgets.

The old fluid cross-section was removed from the surface actor. Use BP_FluxGlassSection (example on FluxSectionMap) to achieve the effect of the water volume cut. Moreover, the new glass rendering mode does not interfere with underwater surface rendering, and the base water shader has been simplified by removing Seciton branches.

Improved underwater volume and surface rendering in underwater section glass after upgrading to a new glass system.

 

Underwater light

Another long-awaited feature introduced in this version is underwater lighting. A New system simulating underwater scattering and working with single-layer water mode is a huge step forward in expanding the possibilities of building the underwater world. There are many ways how underwater lights can be used in your projects:

  • underwater bathyscaphe,
  • lights from a helicopter lighting the water,
  • underwater lights directing the player,
  • rivaling underwater cities,
  • underwater diving with attached flashlights,

The underwater light system brings many exciting features:

  •  Efficient point light implementation (BP_FluxPointLight )
  • Advanced spotlights (BP_FluxSpotLight) implemented as volume ray marching with dithering. Support projecting texture and generating light shafts.
  • Light propagation medium water and air splits the light into two colors.
  • Integration with built-in unreal light system shadow mapping
  • An unlimited number of lights. The system used a system similar to deferred rendering that is drawing lights as meshes
  • Nonphysically correct but controllable scattering and projection intensity provide more variety and allow adjustments.
  • The system can be used with underwater glass. 

Water decal

This feature was added at the request of the user who needed to render decals on water. (Yes, you can have an impact on this project!). After a few tests, I noticed that it is doable and may be valuable for many projects. The new decal actor (BP_FluxDecal) uses unique programmable material that can be implemented in many different ways based on the requirements of the designer; it provides additional functions that generate Decal UV projection and information about the side of the water currently rendered.

The default example decal material uses the Fluid Flux icon texture, but many exciting effects can be implemented with this system:

  • gameplay indicators,
  • rendering additional foam animation,
  • dirt and dust projection on water,
  • blood or oil stain on the water

This feature has a lot of potential, so in the future, I plan to extend it by implementing decal-like volumes and simulated fluids on top of the water surface, which are advected by base fluid velocities.

Static mesh converter and baking

The static mesh mode is the most efficient way to render fluid flux water surfaces. Still, since releasing the Fluid FLux 2.0, it has been entirely forgotten, and it’s time to introduce significant improvements in this topic.

In Fluid Flux 3.0, the static mesh generator was rewritten to a new separate editor actor tool called BP_FluxSurfaceMeshGenerator. The new tool uses the Geometry Scriprs Plugin introduced in Unreal Engine 5, so don’t forget to enable it in your projects!  

What changed:

  • This new tool is now separated from the BP_FluxSurface actor, making the interface cleaner and more encapsulated.
  • The new wireframe preview option dramatically improves the visualization of exported meshes.
  • Baker optimizes mesh density using fast built-in engine geometry scripts, so geometry density is better distributed.
  • Performance issues related to reading render targets were addressed, and the whole generation process is working over 50 times faster.
  • The new static mesh generator provides more precise results and supports bigger meshes, thanks to shortening generation time.
  • Exporting is simplified as the target mesh can be pinned to the blueprint and overridden every time it changes.

The video below presents the optimized output mesh generated in the editor with wireframe preview enabled:

Unfortunately, there are still some limitations:

  • Geometry Scriprs works only in the editor, so generating static meshes in runtime is no longer supported.
  • Generating huge meshes may take some time as the system is implemented partially in blueprints.
  • The generator works only for rivers and lakes. Building static mesh for the ocean does make sense, as it should be dynamic.
  •  The output mesh can’t be blended with the ocean because it uses another surface rendering mode.

Buoyancy Editor

The buoyancy editor is my first attempt to make an editor based on a 3D preview viewport. Previously, configuration buoyancy was quite a challenge as it required restarting the game using temporary debug pontoons and the trial and error method to find proper values. Now it’s different! You can see the preview of pontoons in a separate editor. Configure it in the editor view and watch your adjustment in runtime! All changes are saved in the bouncy data asset to be easily shared between different bouncy components and managed in the content browser.

The EUW_BuoyancyEditor editor can be found in folder /FluidFlux/Editor/Blueprints/ and run by clicking RightButton -> Run Editor Utility Widget.

A tutorial presenting all editor options and documentation describing the workflow is coming soon.

Unified velocity advection

This update brings many changes in how the velocity of the simulation is interpreted inside the Niagara particles and surface shader. In the previous version, the speed of surface waves differed from that of particles advected on the surface. This inaccuracy is fixed by unifying velocity units and transferring them into world space. This improvement allowed me to create exciting examples like advected foam and bioluminescent plankton.

 

As a result of changes, the BP_FluxRotatorActor (FluxRiverMap) detects water velocity correctly, and rotation is calculated precisely from the fluid flow. It is a good start to create complicated mechanisms driven by the simulation.

 

Another fantastic improvement is calling the water speed depending on the depth relative to the surface; this change gives a more realistic effect for objects deep in water as they move slower. The image below presents the scale of velocity when depth changes. This means the FluxData component output may differ depending on the sampling height. The change also applies to all particles in water; the dust on the surface will move faster than dust deep in water.

Chart showing how water speed decreases with depth. The speed drops off exponentially, approaching very low values around 100 meters

Vehicles

Until now, example demo boats were working as floating meshes on water, but Fluid Flux 3.0 introduces a new drivable motorboat implementation that extends this functionality and provides valuable examples:

  • The boat actor uses the new bouncy system configured using a bouncy data asset.
  • Movement is controlled by a single force pushing from the motor attached behind. Parameters of speed and engine can be easily adjusted.
  • Get close to the bot and press E to start driving the vehicle.
  • Additionally, the demo boat implements camera movement with direction adjustment, and it was tested in multiplayer.
  • The implementation can be extended to work as a ship or another type of vehicle.

Rain particles

Some of you asked about integrating the Fluid Flux with other water systems like UDS or Infinity Weather. I cannot provide it yet, but at least this update introduces more functionalities and examples addressing weather-related limitations. I’m presenting a new Niagara particle effect integrated with water that simulates raindrops:

List of features:

  • The effect implemented in the Niagara on GPU.
  • The Niagara effect needs to be used with BP_FluxNiagaraActor to read the information from Fluid Flux water.
  • The system spawns a minimum number of rain particles around the camera and automatically repositions when the camera moves.
  • The spawning area moves with the camera, so it’s essential to set a new BP_FluxNiagaraActor.InfiniteExtend=true flag; otherwise, the effect may disappear when the actor is not in the camera frustum.
  • The collision between the water drop and the fluid surface is made by sampling the surface and comparing the difference between water height and particle position.
  • Spawned particles support three rendering states:
    Water drops spawn particles in camera space and render stretched drops with refraction.
    Water splashes – animated splash billboards generated when a drop hits the water surface.
    Water rings – animated raindrop rings generated when a drop hits the water surface, and moves with the water flow.

Large World Coordinates

The improved version of Fluid Flux handles LWC (large world coordinates) and should work correctly at a distance of up to 150km from the center of the level on the x and y axes. This use-case can be tested on the FluxOceanMap, where you can find the teleport actor that will move the character to another location far from the center of the map. I won’t spoil what else is there; you should try it yourself!   

Pushing Fluid Flux to its limit is crucial for me; therefore, many tests were made on large-scale coordinates. However, it’s important to notice what is the status of this feature:

  • I’ve addressed and improved everything I found: underwater post-process glitches, simulation domain update bugs, disappearing surface meshes, swimming detection, Niagara particle warnings
  • This does not mean the coastline or simulation domain can cover 150km of area. For now, the system is mainly ready for ships traveling through the open ocean.
  • LWC required a workaround based on a respawning effect every few kilometers, which is automated in runtime. However, you may notice some glitches in the editor preview that can be fixed by repositioning the surface actor.  Debug help menu previews show distance from the center.

Underwater

A new curve-based waterline configuration is an entirely new way to set up the precise appearance of the waterline’s refraction light transmittance, shadow, and blur.

Curves representing effects on waterline (red = shadow, green = blur, blue = color, alpha = refraction)

In previous versions, the underwater post-process caused a noticeable banding effect in dark waters due to very low scattered light. The latest update mitigates this issue by using white noise to mask the imperfections.

Notice the soft inrerpolation of the colors on t he right side of the screen.

Other improvements

Optimizations

High performance is crucial for this project. I decided to extend the surface rendering system to select material permutations based on the effect active in a specific area. This means that the system selects possibly the cheapest material by excluding the code needed for rendering simulation/coastline/ocean waves, depending on what the player sees. This change gives a significant performance boost, especially on coastline maps (at least +10 FPS) that previously were the most expensive.

Wind Direction

Additionally, the FluxOceanWave actor supports dynamic changes in wind direction. The blueprint function can control it. The example is presented in the OceanMap level blueprint that randomizes wind and direction every few seconds.

Gernster water (experimental)

The Fluid Flux wave system uses prebaked FFT water animation. This solution is efficient and visually appealing, but unfortunately, it is not configurable enough, and ocean waves look almost the same in every project. New Gerstner water mode is my first test to make water movement more realistic and configurable.
Right now, only surface materials support Gernster water, which means it is only a visual effect because gameplay can’t read water surface height from it yet.

Exporters

  • Unified fixed, improved, and cleaned exporter code now exporting should cooperate better with the repositories.
  • Fixed repetitive patterns on the ocean after exporting the coastline domain data.

Surface actor improvements

  • Added soft references to external content. 
  • Support for nDisplay, raytracing, and path tracing (Experimental with limitations)
  • Added SDF masking support
  • Improved underwater visibility detection
  • Added surface mesh modes based on instanced mesh and configurable mesh dentistry
  • Custom editor for color preset data assets with automatic preview in the editor (Open SurfaceEditorTab)

Use cases

For example, demo levels get a bit complicated. They may look overwhelming for new users, so I added a folder called Demo/Maps/, where I plan to put more straightforward examples, presenting the basic configuration and testing scenario for a specific setup.

Please let me know if you need some specific use cases. 

Future

I never imagined that so many developers would use my product, and this is an excellent opportunity to thank you for believing in my project and using it in many spectacular ways. I am always impressed with your work, and it fuels me to do more stuff, so please don’t forget to share your creative projects with the community on my Discord!

  • Substrate – A separate path for substrate UE 5.5 will be released soon.
  • Scalability – I know you need more extensive simulations, coastlines, and worlds, and I plan to address that.
  • Multiplayer – I plan to implement multiplayer for ocean, coastline, and pre-baked simulation states.
  • Plugin – A new C++ version called Fluid Flux Plugin is currently being developed.
  • Documentation – I plan to rewire documentation and supplement it with additional videos.

That concludes the update. I want to thank everyone for their patience and for discovering and reporting many bugs and improvements. Seeing my pack being used in your unique projects has been gratifying. Thank you all!

A new C++ version called Fluid Flux Plugin is currently being developed. The new version is nearly complete, and it will be available early next year (2025).

For now, I can only present a short list of differences in the first release of the Plugin:

  • Improved usability, enhanced editor tools, and better integration with Unreal Engine UI
  • Simulation domain implemented in Niagara and new spline modifier
  • Whole blueprints code rewritten to C++ (Github access)
  • Improved performance (mainly CPU related)
  • Better sequencer support

The Fluid Flux Plugin will be primarily targeted at larger studios and experienced developers, and it will be released as a separate product on FAB. While it’s not exclusive, please note that modifying the C++ version will require programming skills and some extra work on transferring existing projects, which I did not want to force on current Fluid Flux users.

What about Blueprints after the Plugin release

Many concerned developers ask about the blueprint branch of the Fluid Flux. The excellent information is that The new programmer has joined to work on C++, so I can still focus on updating blueprints. 
I plan to continue adding new features and enhancing tools as long as possible.

However, I am unable to tell for how long I can support two different branches of the product. I will evaluate the situation after one year from the Plugin release (early 2026). A possible scenario is that I will switch focus to the C++ version and only provide minor improvements and engine-related updates to the blueprints. However, my final decision depends on many factors, such as:

  • Interest in Pluign in comparison to the Blueprint version. If most users decide to switch and prefer to use Plugin, then there is no reason to continue development.
  • Whether the BP version can still evolve, the blueprint’s limitations block many features, and at some point, adding another workaround may be too problematic.
  • The complexity of transferring asset-related changes between the two versions. It may be exaggerated significantly when the differences between the two branches of the project are growing.

This information may concern those who have already invested in the Blueprints version of my product and are now interested in using the Plugin. I understand that, and I am looking into possible discounts for current owners of Fluid Flux.

However, there are also some voices of dissatisfaction in reviews that I feel obligated to address by reminding that:

I sell the products ‘as is,’ and customers should base their decision on the product’s current state (demo and feature set), not on theirs future expectations or announced features.

I don’t sell promises, future versions, my free time, or lifetime updates. I also don’t work for markeptlace clients. Please avoid basing your project’s timeline on unreleased features.

Every update is an additional effort driven by my passion for creating. Being obligated to complete something by a specific deadline can cause stress, and I prefer to avoid it.

 

Thank you for understanding

This document provides essential guidance on reporting system errors. Learn how to identify, report, and analyze bugs to ensure smooth support.

Before requesting support

Most of the issues are already known and can be easily avoided by you, which is why I prepared this checklist.

  1. Check the product’s limitations; there is a chance that your use case is not handled yet.
  2. Ensure that the bug is not listed in the ‘known issues’ of the product. 
  3. Read the documentation, mainly focusing on the chapters titled ‘Solving issues‘, which cover the most common problems.
  4. Check the marketplace launcher and ensure you use the newest version of the product.
  5. Ensure you are my client and use the product from legal sources; support may require verification.

Discord support threads

The support channel is based on thread conversations. Every question/request will start from a new thread, which makes it easier to follow separate discussions and provide direct support.

  1. Use the support channel ONLY if you have bought my product and need my help.
  2. Use a general channel to talk with other people on Discord.
  3. The bot will create a new thread after you send a question to the support channel.
  4. Add more details in your thread per the chapter “Preparing bug report.”
  5. Don’t stack multiple questions at once. Let’s focus on a single problem and solve it one by one.
  6. Write only in your thread; don’t start another thread conversation until your problem is solved.

Please obey the thread’s rules; otherwise, you will not get my support and can be suspended for a while.

Preparing bug report

I’m doing my best to help everyone, fix all bugs, and work around the engine limitations, but some configurations may still cause problems. Reporting issues helps improve the product. Preparing a precise bug report is crucial in increasing my response time and chances that I will solve the problem and show professionalism. 

  1. Write information about your configuration.
    • The Unreal Engine version you use
    • List of specific config settings enabled in the project (Lumen, Ray Tracing, Path Tracing, Forward Shading, Nanite, Substrate, and everything that you think could cause the issue)
    • Development Platform (Windows, Linux, MacOS)
    • Target Platform  description(VR device, Mobile, MacOS)
    • Add information if you can see the same issue in the example demo maps
  2. Prepare visual materials presenting the problem
    • short video
    • screenshots
  3. Write a clear and detailed explanation with the steps needed to recreate the problem on my machine. 
  4. Explain the result you want to achieve after solving the issue.
  5. Attach a minimal project presenting the issue (see below for a description of how to do it).

Minimal project

The easiest way to receive fast and direct support is to send me a minimal project demonstrating the problem. This reduces the time needed to reproduce the issue on my PC, which is often the most challenging part. Please read the description below to ensure that the minimal project aligns with the requirements:

  1. Download my product into the small (empty) project and reproduce the bug.
  2. Prepare repro steps.
    • Add information on which level should be opened
    • Add a list of steps to repeat to see the bug in your map
    • Add details on testing the target platform
  3. Minimalize the size of the project:
    • Remove all content (textures/meshes) that are not crucial for the presentation of the bug,
    • Remove “Intermediate”, “Saved”, and “Build” folders,
    • Disable all external plugins and ensure the project does not depend on them.
  4. I do not download files from unknown sources, so you must verify yourself by sending me the order ID via email or private conversation/email.
  5. Make sure that the bug can be reproduced with your description. Test it!
  6. Pack it (zip), upload it on the server, and send the link to me via support email at imaginaryblend@gmail.com. 

Don’t share minimal projects publicly on Discord or the marketplace questions tab. Always use the support email for sending the files imaginaryblend@gmail.com.

Reducing support response time

I receive numerous support requests and questions daily. Good communication practices and rules can simplify our work, reduce stress and irritation, and save time.

  1. Please use the support email or marketplace questions tab (I prefer it to Discord). Don’t ask for support in the YouTube/X comment section.
  2. Be precise and professional. Please give me as much information as possible (read: preparing bug report). I always respond faster to requests when they are clear and easy to understand.
  3. Be polite and patient; support may take a few days. If you don’t hear back, please send your request again or message me on the Marketplace Questions Tab. Your message might have gone to spam, or I missed it.
  4. I do not download files from unknown sources, so you must pass verification. The only way to verify is by sending me the order ID via email or private conversation/email.

Now you can report this bug by sending an e-mail to imaginaryblend@gmail.com

Introduction

 
Fluid Flux Update 2.1 brings a set of important bug fixes, stability improvements, and modifications added as a direct response to support requests, which makes the user experience even better. The new version of the pack is compatible with Unreal Engine versions 4.26 – 5.3. A detailed list of changes and a roadmap presenting what is planned can be found on Trello.
 

Before updating the Fluid Flux in your project please read carefully the Package Update Process. Following the update procedure ensures a smooth transition and minimizes the risk of potential issues arising during the update process.


Infinite Ocean example map

A new example map in Fluid Flux 2.1. The new map showcases the infinite ocean setup and large-scale stormy waves. This simple example does not use any domains, which makes it super efficient.

TSR Motion Vectors

I’ve improved motion vector generation in surface material, significantly improving water rendering quality. I’ve also added slope velocity, which fixes noisy smearing on the waterfalls. The new motion vectors generated from world position offset work well in Unreal Engine 5.3, so I recommend switching to the latest engine version). For the best experience, use this configuration in your project settings:

  • Velocity Pass = Write During Base Pass
  • Default Renderer Motion Vector Settings = Precise

Minor issues and bugs may still occur on distant water, and I will work on them in future updates.

Underwater shaders

  • replaced old nosy random-based circle blur with a 5×5 Gaussian blur.
  • Fixed underwater post-process masking. Now, the post-process disappears when the camera is under the ground map.
  • Added underwater visibility enum in the surface actor that allows forcing visibility of underwater post process. The new InsideContainer mode allows rendering post-process through glass (an example of use with glass material will be presented in the next update).

Ground and Domains

  • fixed foliage filtering, UseFoliageMeshes works properly now.
  • Improved the ground map and phantom meshes debug rendering.
  • Enhanced performance of ground map rendering and building the visibility list.
  • Fixed rendering of distant landscapes with a lower level of detail.
  • The coastline domain can now cut out fragments of the ocean on the landscape.
  • Fixed brush editing when the initial state is active.
  • The “Current state” in domains changed to transient fixes memory crashes.
  • Domains will not update when dragging actor move, only after the drop.
  • Fixed simulation streaming on a separate level.
image.png
The area is submerged below the ocean’s surface, yet a phantom mesh excludes the water, allowing players to access this region.

Other improvements

  • Adjustments for distant surface rendering. I added OceanWaveRange and OceanWaveFaloff parameters that give additional control.
  • Fixed weird overburned emissive when the camera is very high.
  • More than four buoyant pontoons have been supported since now.
  • Fixed all buoyancy problems in shipping builds.
  • Added the tag FluxBuoyancyOwner that allows specifying the target actor for pontoons attachment.
  • IsSpartiallyLoaded = false in all crucial Fluid Flux actors fixes world partition bugs.

Enhanced input

Switching to Unreal Engine 5 unlocks the possibility of using all of its goodies, and the Enhanced Input is one of them. The whole input implementation is now stored in data assets, which can be included in the product. Fluid Flux does not require downloading any additional config files.

I’ve also cleaned up the character implementation and moved world control to the player controller, making it easier for everyone to understand.

Demo on itchio

The executable demo was also updated and published on Itchio. There are many reasons for that change:

  • This platform is a bit more professional than Google Drive links and may feel safer for others.
  • I can send notifications about the new version to everyone who has my demo in the collection.
  • I can also push many builds (mobile, VR, PC, Linux, Mac, Vulcan) and manage them better without replacing links on the marketplace page and in my videos.
  • Everyone can comment, and I can see additional details about downloads/users.

What Next

This update will be the last one supporting UE 4.26 to UE 5.2. Moving forward, my focus will shift exclusively to updating the package for Unreal Engine 5.3+. I apologize to everyone who is unable to transition to UE5.3 at this time. There are several reasons for this decision:

  • TSR doesn’t look acceptable on early versions of Unreal Engine 5, which makes working with it uncomfortable. I highly recommend switching your projects to Unreal Engine 5.3.
  • Creating a package with backward compatibility for older versions of UE is time-consuming and requires excessive effort. I prefer to spend this time on improving the product.
  • This shift will open up many exciting possibilities for optimizations and improvements, making my work much more manageable.

Installation

This chapter covers the initial installation of the product in your project. If the product has already been installed in your project, skip to the “Updating Process” section below.

Due to limitations of the FAB Marketplace, the launcher library may not display the latest product versions. The description below outlines the complete process for installing Fluid Flux to ensure you are using the most up-to-date version.
 
  1. Install and enable the “FAB Plugin” in your engine.
    Fab Plugin Inside Unreal Engine 5.4 - Feedback & Requests - Epic Developer  Community Forums
  2. Run your project and find FAB in the Content Browser, and after opening the window, make sure you are logged into FAB in your editor. r
  3. Browse the Fluid Flux and open it (double click).  
  4. If you have already bought the Fluid Flux, you should see an “Add to Project” button. This may need a clean FluidFlux folder to work and Backup your project before doing so. 

Updating process

Due to the extensive scope of package updates, certain aspects might have been overlooked during the development and testing phases, and it may be dangerous for your project, so make sure you will have at least a few days to fully integrate the new version with your project in case you need my help.

Changes that update may include:

  • Adding new features and example maps
  • Enhancing memory management, fixing bugs, optimizing performance,
  • Ensuring compatibility with the latest technologies,
  • Providing a better user-friendly experience,
  • Improving quality and efficiency,

However, be mindful of potential issues when updating.

  • Removing, renaming, moving files and attributes,
  • Overriding your changes,
  • Adding new bugs,

I strongly recommend using a version control system (Perforce, GIT, SVN) for your projects, which is the safest way to avoid unexpected problems and blackout changes. Making a copy of your project before downloading the update is strongly recommended to ensure a smooth transition.

Please note that I might not automatically handle the removal or renaming of assets during the update process. Consequently, there is a possibility of “ghost files” from the previous version of the product. To mitigate any potential issues, it is recommended to follow these steps for updating:

  1. Ensure that the update for the engine version you use is already available on the marketplace page.
  2. Navigate to the Content/UpdatedPackage folder in your project.
  3. Copy the Content/UpdatedPackage for backup in case of unexpected issues that may occur after the update.
  4. Remove or delete the entire old version of the product from the UpdatedPackage folder.
  5. Download the new version of the product and extract it into the UpdatedPackage folder, ensuring a fresh and clean update.
  6. Run your project, test the example maps in the demo folder, and check if the product still works correctly with your project.

It’s best to avoid making modifications to the pack by yourself. If you need to make changes, I recommend inheriting classes/materials and overriding functions. Store child classes and custom material instances outside the pack folder. If you need minor trivial modifications that could improve usability, you can let me know. We will figure out some solution and maybe put it into the next update.

In case of any problem, contact me using the support email at imaginaryblend@gmail.com.

 

 

Imaginary Blend Refund Policy – Terms and Conditions

This refund policy ensures fairness for all customers and creators in the Unreal Marketplace. Refunds are typically granted for faulty products or those not functioning as intended.

Unreal Marketplace Refund Policy and Marketplace Refund Guidelines can be applied in most cases.

Due to a rising number of fraudulent attempts to demand refunds immediately after purchase without particular reason, I find it necessary to implement a refund policy to outline the guidelines clearly.

  1. Refunds are applicable under the following conditions:

    • A bug within the Marketplace item prevents you from using it as advertised.
    • The description, screenshots, or video in the Marketplace do not accurately reflect the content of the Marketplace item.
  2. By making a purchase, you acknowledge the product limitations, especially the following:

    • The product’s documentation outlines its constraints, and it is essential to review them before purchasing.
    • Product demos showcase typical use cases for which they were created and thoroughly tested.
    • If the product’s capabilities are uncertain, inquire and ensure that it meets your expectations.
    • Make sure that the product supports the Unreal Engine version that you use.
    • The purchase pertains to the current version of the product, not future planned changes. If a required functionality is absent in the current product version, consider holding with the purchase.
    • The creator sells products on the marketplace ‘as is’ and does not guarantee future updates.
    • The creator of the product does not undertake the development of your project.
  3. The refund will not be approved in the following cases:

    • “I thought it would work differently.”
      Read the documentation and listed limitations before purchasing. In case of ambiguity, inquire on the product page to ensure your expectations can be met.
    • “I wanted it to be more realistic.”
      Before purchasing, test the executable demo showcasing the product’s possibilities. The demo is available on the marketplace page.
    • “I didn’t know it won’t work on Mobile and VR, PathTracing, Ray Tracing, Lumen, Sequencer.”
      Customers must review the description for information and inquire about specific technologies or design details.
    • “I’m a beginner; I don’t know how to use the engine; nothing works; I need tutorials.”
      The product is intended for experienced users of the Unreal Engine. Support questions will be answered, but the creator is not obligated to teach how the engine works.
    • “I wanted to create an open-world multiplayer, but it’s impossible.”
      Creating open-world games is challenging due to the extensive design and development required to craft a seamless and immersive environment. The requirements cannot be precisely defined. By deciding on this genre, you implicitly accept the difficulties associated with the problems you will encounter.
    • “The product was expensive, and I need my money back now.”
      Please do not act impulsively; make wise decisions before purchasing the product.
    • “I did not read the refund policy before the purchase.”
      Being unaware of the law is not considered an excuse.
  4. Refund process

    • Only Epic can issue refunds for Marketplace items.
    • Before requesting a refund, contact support through imaginaryblend@gmail.com or use the “Questions” section on the Marketplace to get help.
    • Refund requests must be made by submitting a Marketplace Refund Request Case within 14 days from the date the transaction took place.
    • The seller has the right to request verification of your refund history to determine whether it is fraudulent.
    • When the marketplace support team decides to leave the decision about a refund to the seller, the “Imaginary Blend Refund Policy” applies.
  5. In case of issues with downloading the product

    • Ensure the product supports the engine version for which you are trying to use the product.
    • Restart the Marketplace launcher to refresh products on your list.
    • Contact the marketplace support team to resolve the issue.

Gallery  

Executable demo

The executable demo is available for free on itch.io. Please try the demo before purchasing.

Features

  • Realtime shallow water simulation – fluid data modifiers, wave generator, and extendable interface
  • Fluid surface rendering – caustics, wetness, underwater, waterline, advected foam, advected waves, blending with the ocean, dynamic audio detection.
  • Fluid Interaction – simple cheap ripple solver moving with character, optimized to an absolute minimum
  • Ocean wave blending  – rendering tillable ocean heightmap texture in a single pass
  • Niagara environment interaction – High-quality effects, bouncy plants,  character swimming, boats, 
  • Clean, efficient, GPU-friendly implementation, interface designed with the KISS (Keep It Simple, Stupid) rule in mind
  • Tool for generating ultra-fast static meshes with flow maps baked into vertex color and uv.
  • Advanced fluid state management and loading state in gameplay.
  • Niagara fluid async readback system for sampling height and fluid flow in blueprints.
  • Dynamic audio analyzer. The sound source is positioned based on fluid movement.
  • Velocity-based fluid flow advection method for foam caustics and waves
  • Possesable vehicle system implemented especially for boats
  • Underwater glass and spline-based tunnels, lights, decals
  • Coastline wave break rendering
  • Replicated ocean waves and vehicle movement
  • Simulation-driven surface particles (leaves and dust)

Limitations

With great power comes great responsibility. I am committed to being a reliable marketplace creator, so I must communicate the limitations and disadvantages of using simulations. The Fluid Flux system is somewhat overhyped, so please, before purchasing, read the description below and ensure that everything aligns with your expectations and requirements. Ensuring that is crucial for the Refund Policy

The system is advanced, so it may be overwhelming for beginners. The code is clean and elegant, but blueprint reading skills and example code analysis are required.


Shallow water simulation

  • The Fluid Flux simulation is based on the Shallow Water Equations (SWE). It is calculated in 2D on a heightfield mesh, meaning all obstacles are rendered to a height using top-down projection. Fluid can not be simulated in caves. However, the algorithm can ignore particular objects, such as bridges, so they do not interfere with the simulation. 
  • While Fluid Flux represents a significant advancement for the game industry, it also introduces additional challenges. Controlling and adjusting simulations can be demanding; sometimes, a single parameter change can alter the fluid flow across an entire map.
  • The simulation area can’t be rotated. The product supports only axis-aligned rectangular volume.
  • The simulation area can’t be moved in runtime. Movable volume is one of the most important features for future updates.
  • The simulation domain does not support the wave break effect because the fluid approximation does not contain the needed data to render it.
  • Niagara fluid readback used for buoyancy and fluid detection returns results with (at least) one frame delay. It’s good enough for most features like swimming fluid detection but not 100% reliable. Trace hits with dynamic fluids are not supported now.
  • Simulation is deterministic under certain conditions: the same machine and simulation parameters. Still, there are probably differences between floating-point operations on different GPUs, so it can’t work fully deterministic.

Known issues

  • “Real-Time” render mode is required to simulate in the editor. Otherwise, the view will not refresh after each frame. Plants also will not load properly on the map if you are not in “Real-Time” render mode in the editor. Its limitation of blueprints: I don’t have any event that could be executed after loading and adjusting Niagara effects.
  • Rendering underwater translucent mesh is a challenging problem to solve. Single-layer water materials do not support translucency, so translucents are invisible when watching surfaces from above water. The Fluid Flux mesh-based post-process material implementation is more functional because it can be overlayed before translucent meshes.
  • Shadows on water may look a bit blocky. This is a limitation of the single-layer water material in Unreal. Epic improved it in version UE5.3, and it should look better.
    You will have to enable Virtual ShadowMaps, and you will also add those lines to your DefaultEngine.ini:

    r.Water.SingleLayer.DepthPrepass=1
    r.Water.SingleLayer.ShadersSupportVSMFiltering=1
    r.Water.SingleLayer.VSMFiltering=1

  • The maximum heightmap range is 32000 units. This limitation was introduced with Unreal Engine. The problem concerns rendering clamped colors to render targets for unexplained reasons.
  • Single-layer water material mode is not supported on mobile. It’s an engine limitation that Epic Games should solve. Generally, this material mode does not support the absorption coefficient on mobile, so water will look differently.
  • Path tracing is not supported because Single Layer Water mode does not work.
  • The PS5/Xbox shader compiler defaults to 16bits float per channel, which means you will have to lower the precession settings in the simulation domain to make it work on console platforms.  Unfortunately, this change may cause water loss, as 16bit is not precise enough to simulate conservative water flow in the long term. Please pay attention when your gameplay depends on simulation results.
  • Statically generated mesh of water can be inconsistent with waterline post-process. This issue will be addressed in the future.
  • The underwater post-process effects in VR mode only work when Project Settings > VR > (enable) Instanced Stereo = false. This rendering mode breaks rendering the translucent meshes and should be disabled.

Scalability

The simulation domain requires allocating floating-point render targets and updating every frame, which may cost a lot.  
The size of domains can be increased by changing the precision of details per simulation cell.  Ocean setup does not require allocating memory, but rendering water is limited by floating-point calculations. You may encourage many unpredictable behaviors like disappearing post-process and surface far from the center of the map; 20 km in every axis is the limit.

Domain Resolution

Precision

Maximum domain size

Simulation up to 1024 x 1024  up to 100 cm per pixel 1km x 1km  
Coastline (island) up to 2048 x 2048 up to 1000 cm per pixel   20 km x 20 km (pixel size 500 cm)
Ocean n/a  n/a 40 km x 40 km (limit of floating point)

Performance

Many users are concerned about performance and don’t know if it requires a high-spec PC. Performance depends on the GPU, rendered resolution, and enabled engine options, but the product is prepared even for older devices and can be adjusted for more demanding projects.

I heavily recommend downloading the demo and testing it on the target device. Example results of my tests are presented below:

GPU Resolution River map Island map
RTX 3080 2560×1440 320-380 FPS 260-310 FPS
RTX 2080 2560×1440 160-200 FPS 110-160 FPS
GTX 860M in 8 years old notebook Lenovo Y50   1920×1080 25-30 FPS 20-25 FPS

In the case of bigger maps, efficiency may sometimes be a problem. I recommend avoiding the use of simulation resolutions larger than 1024×1024 in games. The calculation of a large-scale simulation often requires a substantial number of computations. I suggest utilizing the lowest feasible resolution for the simulation. For example, the maximum resolution in the example demos I provide is 1024×256 (BeachMap). The simulation frame can be baked into data assets and rendered without the additional cost of updating the simulation, which is incredibly efficient and valuable for rivers. You can also lower memory consumption by additional compression. 


Multiplayer

Fluid Flux is not inherently designed for multiplayer environments. However, under specific conditions and certain limitations, it can be utilized in multiplayer scenarios as a visual addition through carefully crafted gameplay design. This chapter outlines the challenges, technical limitations, and potential workarounds developers should consider when integrating Fluid Flux into multiplayer games.

The table below presents the current status of multiplayer support inside different domain types.

Domain type  Status Description
Ocean Replicated   The server sends the wave time and wind settings to the clients.
Coastline Client-side Coastline time replication has not been implemented yet.
Simulation (dynamic) Client-side It can easily desynchronize between the client and the server. The wave generator uses render time, so it is not yet deterministic.
Simulation state Works The state is the same for the client and server. It does not require any replication.

Technical Limitations

  1. Client-Side Simulation: Fluid Flux uses Niagara readback to sample water data, which is essential for GPU computations. However, Niagara does not function on dedicated servers, making it impossible to process critical data from the server side. Simulations are calculated client-side only, and the results of Niagara Readback are automatically sent to the server. This approach is unsafe for games that rely on an authoritative server, which can be problematic for competitive gameplay.

  2. Bandwidth Constraints: The simulation involves substantial dynamic data changes, which are challenging to synchronize over a network due to limited bandwidth. Transmitting large amounts of fluid data in real-time is impractical for most multiplayer setups. Simulations can quickly desynchronize without mechanisms to correct discrepancies between the server and clients, leading to inconsistent results across players.

  3. Non-Deterministic Behavior Across GPUs: While the simulation is deterministic on the same machine under controlled conditions, floating-point operation differences across GPUs can result in minor discrepancies, complicating synchronization.

  4. State Recovery Issues: Synchronizing the simulation’s state is particularly challenging when new players join, or frame spikes occur. The system cannot smoothly recover from these situations, even with limits on accumulated iterations per frame. In situations like this, storing prebaked states of simulation could be loaded after the player joins the game is recommended. For example, the state of water that the client should load when the dam is broken.

  5. Vehicle Replication: The demo maps include a drivable board system that works in multiplayer. However, client-side movement lacks smoothness and would require external plugins to improve the physics replication of actors. Unreal Engine 5.5 introduces features like the “mover” and enhanced physics replication for multiplayer games, which will be utilized in future versions of Fluid Flux.

Fluid Flux’s multiplayer capabilities are experimental and come with notable limitations. It’s not recommended in competitive gameplay. Developers should weigh these limitations carefully and design gameplay around them to ensure a stable and enjoyable experience for players.


Open-world

The accurate open-world setup has not been tested. The demo examples show how the system can be used. I can’t promise anything more at this point of development. Just assume that you get what you see in my videos, no more, no less.


Voxel Plugin

Yes, you can use Fluid Flux with Voxel Plugin, but it is also limited to heightfield projection, so caves and planets are unsupported.

Use Simulation.RuntimeCaptureDelay = 1.0 to force simulation to wait for the voxel plugin map to generate mesh before rendering it to the height map.
The heightmap in this presentation is updated every frame using CaptureGroundHeightmap. It is inefficient and should probably be optimized only to update the area around the brush when something changes on the map. The UpdateGroundMap(Position, Size) function would be a better choice.


Good and bad practices

  • Avoid using a large simulation resolution because you will quickly run out of memory; 1024×1024 seems like a good compromise.
  • Don’t make your gameplay rely on fluid simulation in multiplayer because it can’t be synchronized.
  • Avoid using Fluid Flux on flat surfaces; subtle slopes are always better.
  • Avoid hard-edged geometry (boxes). It can be approximated wrongly in height maps, and steep slopes sometimes look terrible.
  • Try not to overestimate this system. If I haven’t prepared the ocean with ships and a vast island covered by rivers and simulated lakes, there is probably a reason for that.
  • Try not to update the simulation ground in every frame. It may cost you a lot of performance.
  • Meshes using the materials with “PixelDepthOffset” active may not render appropriately into a ground height map. A simple workaround is described in the chapter Ground Capture->Solving issues.

Questions & Answers

  1. How it works?
    The Fluid Flux simulation implementation is based on the Shallow Water Equations (SWE) solver. The algorithm was published by Matthias Müller in “Real-time Simulation of Large Bodies of Water with Small Scale Details”. Simulation is calculated on heightfield mesh, meaning all obstacles are rendered to heightmap using top-down projection. Fluid flows in X and Y directions between cells of the grid that describes the volume of water. Forces that move fluid are calculated based on the difference in ground + water height in neighboring cells. The coastline system uses the signed distance field to describe the edge intersection of water with the ground and renders animated wave profiles based on wave movement.
  2. Can I use Fluid Flux in my game if I purchase it?
    Take a look into the general unreal marketplace license. You can use it in your projects/games and release it in-store. However, you are not allowed to publish/sell the product’s source code. If the Unreal Engine licensing model does not fit you, contact support so we can create a custom license to match your unique and specific requirements.
  3. Why is the price so high? Can you offer any promotions or discounts?
    • Creating a Fluid Flux required over three years of research and development. Typically, a system of this nature would cost the company at least 350,000 USD. The current price makes it a significant time and cost-saving solution for everyone.
    • This kind of system requires a lot of support, especially with ongoing engine updates. Since I have other products on my marketplace profile, my time is currently limited. I have already quit my regular job to focus entirely on developing and improving products.
    • The asset combines several significant features designed to work together, making your development process more accessible seamlessly. You no longer need to purchase multiple separate products and spend time integrating them. It includes a ripple solver simulation, shallow water fluid simulation, water surface rendering, ocean wave generator, buoyancy support, waterline effects, post-processing capabilities, coastline rendering, and even support for Niagara particles. I have handled all these aspects, so you don’t have to worry about them.
    • Please check my marketplace profile to confirm that I am a trustworthy creator with hundreds of positive reviews. The price of my products is always determined based on the work and time required to develop them. Eventually, you will realize that time is a genuine currency with significant value.
    • There will be a promotional sale, but first, I must feel ready to support more customers. If you are not in a rush, add my product to the wishlist and wait patiently. If you want to be notified a few days earlier about a promotional sale, join my Discord server.
    • I am not forcing anyone to buy my product. There are alternatives like Niagara Fluids and Water Plugin. You can try them for free and compare the results with my demo. Maybe you don’t even need the Fluid Flux. Choose wisely.
  4. External packs integrations ALS/UDS/Fluid Ninja 
    I plan to work on some integrations in the future. If you have a specific pack in mind, let me know.
  5. Can I use it with Voxel Plugin?
    Yes, you can use Fluid Flux with Voxel Plugin, but it is also limited to heightfield projection, so caves and planets are unsupported.

    Use Simulation.RuntimeCaptureDelay = 1.0 to force simulation to wait for the voxel plugin map to generate mesh before rendering it to the height map.
    The heightmap in this presentation is updated every frame using CaptureGroundHeightmap. It is inefficient and should probably be optimized only to update the area around the brush when something changes on the map. The UpdateGroundMap(Position, Size) function would be a better choice.
  6. What about VR and mobile?
    I currently do not support VR devices and mobiles.
    Dynamic fluid simulations with high precision can’t be calculated on mobile, so only baked meshes/states can be used on this platform. I am planning to add VR and mobile support in future updates. The pack will receive a cheap surface material mode similar to the solution presented in Aquatic Surface. One user notified me that my demo maps are working without issues on Oculus Quest 2, but I have not tested it yet, so I can’t confirm it.
  7. How to add swimming to ALS? Can you show me?
    This task heavily depends on the character implementation, so I can’t provide an implementation for ALS. The Fluid Flux BP_FluxDataComponent delivers all the data you need to implement swimming. I’ve also prepared an example swimming implementation (BP_FluxSwimmingComponent) for the default engine mannequin so you can check it and learn.
  8. Why blueprints? Is Fluid Flux slow because of that?
    This system is fully implemented in blueprints but relies mainly on GPU (shaders/render targets). Yes, it might be faster in C++, but it would also stretch the development time. The cost of blueprint code will be reduced using Niagara in the future, making it work even better.
  9. Is the Water plugin supported?
    Water Plugin is not supported. Combining my water material with the water plugin mesh is possible but not officially supported.
  10.  Do I need this pack? Should I switch to Fluid Flux? Is it better than WaterPlugin/Oceanology or Aquatic Surface?

    It depends on your specific requirements. The Fluid Flux excels at creating dynamic river simulations on heightfields and interactive scenes but doesn’t scale very well. If you only need a background ocean without detailed simulations, you might not want to go through the trouble of using simulations. However, Fluid Flux 2.0 introduces a new coastline domain system that can handle landscapes of up to 10km x 10km and provides an infinite ocean. I recommend playing the Fluid Flux demo to understand better whether it aligns with what you’re looking for.

    You probably don’t need it if you can’t see the reason for purchasing Fluid Flux! I’ve prepared a simple comparison of  the Fluid Flux and my other product, Aquatic Surface, that visualizes the difference:

    That does not mean Aquatic Surface is bad. It’s a great product with a completely different feature set. You have to choose a product that fits your requirements.


Updates

Fluid Flux has received numerous updates, all provided free of charge to existing users.

You can keep track of the current progress of improvements on Trello. Numerous updates are planned, but I don’t have a specific timeframe. It’s essential to base your purchasing decisions on the product demonstrated in the demo rather than relying solely on my promises.

Please note that I don’t sell promises, future versions, free time, or lifetime updates. I also don’t work for marketplace customers. I sell the products ‘as is,’ and customers should base their decision on the product’s current state (demo and feature set), not on future expectations or unreleased features.

Every update is an additional effort driven by my passion for creating. Being obligated to complete something by a specific deadline can cause stress, and I prefer to avoid it.

Release notes

  1. Fluid Flux [1.1], Performance and usability improvements.
  2. Fluid Flux [2.0], Coastline effects, and water break.
  3. Fluid Flux [3.0], Underwater glass and lights

C++ Plugin

A new C++ version called Fluid Flux Plugin is currently being developed. The new version is nearly complete, and it will be available early next year (2025). For now, I can only present a short list of differences in the first release of the Plugin:

  • Improved usability, enhanced editor tools, and better integration with Unreal Engine UI
  • Simulation domain implemented in Niagara and new spline modifier
  • Whole blueprints code rewritten to C++ (Github access)
  • Improved performance (mainly CPU related)
  • Better sequencer support

The Fluid Flux Plugin will be primarily targeted at larger studios and experienced developers, and it will be released as a separate product on FAB. While it’s not exclusive, modifying the C++ version will require programming skills and extra work on transferring existing projects, which I did not want to force on current Fluid Flux users.

Many concerned developers ask about the blueprint branch of the Fluid Flux. The excellent information is that The new programmer has joined to work on C++, so I can still focus on updating blueprints. 
I plan to continue adding new features and enhancing tools as long as possible.

However, I cannot tell how long I can support two different product branches. I will evaluate the situation one year after the Plugin release (early 2026). A possible scenario is that I will switch focus to the C++ version and only provide minor improvements and engine-related updates to the blueprints. However, my final decision depends on many factors, such as:

  • Interest in Pluign in comparison to the Blueprint version. If most users decide to switch and prefer to use Plugin, then there is no reason to continue development.
  • Whether the BP version can still evolve, the blueprint’s limitations block many features, and at some point, adding another workaround may be too problematic.
  • The complexity of transferring asset-related changes between the two versions. It may be exaggerated significantly when the differences between the two branches of the project are growing.

This information may concern those who have already invested in the Blueprints version of my product and are now interested in using the Plugin. I understand that, and I am looking into possible discounts for current owners of Fluid Flux.

Support

The weakest point of this product is its documentation, which may be incomplete in some areas. I may not excel at explaining things, but if you have any issues, I will try to resolve them. Please don’t hesitate to contact me.

Contact

I always answer support questions, but my availability is limited due to the many requests. I am concurrently working on updates to improve quality and efficiency. If there is no response, ping me again after a few days. If you have any questions or need assistance, feel free to reach out to me in one of the following ways:

Refund Policy

This refund policy ensures fairness for all customers and creators in the Unreal Marketplace. Refunds are typically granted for faulty products or those not functioning as intended. Please Refund Policy

Reporting bugs

This document provides essential guidance on reporting system errors. Learn how to identify, report, and analyze bugs to ensure smooth support.

License

The product is distributed under the Standard FAB license.  

You can use this product in your projects and games, including releasing them on storefronts. However, distributing or selling the product’s source code is strictly prohibited.

If the standard Unreal Engine licensing model doesn’t meet your needs, please get in touch with me directly to discuss a custom license that aligns with your specific requirements. Please note that I do not offer free trial versions, educational licenses, or custom discounts.