[Updated] Fluid Flow 2.5 - Realtime Flow Simulation

Hi everyone!
Fluid Flow version 2.5 is now online!

Fluid Flow allows you to paint fluid to your objects in real time, and simulate it flowing down the surface dynamically. Use it for blood, paint, or any other kind of fluid.

The main feature of Fluid Flow is the dynamic flow simulation.
However, you can also use it just for real-time 3D texture painting/decals, which also supports skinned mesh renderers.

️Try the WebGL demo!
Check out the Documentation!
Asset Store

:zap: The texture painting and flow simulation are handled fully on the GPU for optimal performance!

:sparkles: New Particle-Based flow simulation!
:sparkles: Project Color, Normal, or Fluid Decals!
:sparkles: Draw Color and Fluid using 3D shapes!
:sparkles: Update Gravity maps at runtime!
:sparkles: Flow reacts to Skinned Mesh Deformations, and Normal Maps!

Fluid can flow over UV-seams!
UV-seam artifacts can be hidden! Good UV unwrap is still needed.

Clean high performance code, with minimal dynamic memory allocations!
Utilizing Jobs and the Burst compiler!

Custom Editor tools for easy setup!

Due to its modular structure, you can decide which parts of Fluid Flow you want to use, without unnecessarily bloating your project.

Fluid Flow is not a physically accurate fluid simulation, but it provides good-looking fluid for your games at a comparable low performance cost!

As fluid is painted and simulated in UV space, your meshes require a UV unwrap with non-overlapping UV islands, so there is a 1:1 correlation between the object’s surface and the texture.

Please note that your objects require a specialized shader for overlaying the fluid, or when using the texture atlas system. There are basic surface and shader graph shaders included. Alternatively, you can easily create your own supported shaders with the provided custom shader graph nodes, or shader utility functions.

:white_check_mark: Works with any Rendering Pipeline.
:white_check_mark: Full source code included.
:white_check_mark: Tested on Windows, Android, and WebGL! Should work on any platform!
:white_check_mark: VR/XR Support!

If you have any further questions or suggestions, feel free to contact me here or via email: mr3d.cs@gmail.com

Bravo sir! I can see some great applications here and am interested in purchasing. Can you confirm if this system is compatible with the HDRP in 2019.1? Thank you!

1 Like

Hi, I am glad you like it!
The compute shaders used for the fluid simulation will work independently from the render pipeline you are using.
But I think the shader used to draw the fluid texture on the object will not work with HDRP.
It should be pretty easy to write one with shadergraph though. This will definitely be included in the next update!

I have not played with HDRP much so far, but I have just plugged together a small shader in shadergraph wich seems to work fine.
So just mail me if you run into any problems :slight_smile:

1 Like

Thanks! I’ll play around and look forward to the update.

Version 1.1 is now released!

fluid simulation time is decreased by up to 50%
reduced vram usage
added shaders for LWRP and HDRP
other small fixes and changes

Version 1.2 has been released!

added fluid evaporation
reduced size of ‘FluidObjects’ by 50%
added possibility to further compress ‘FluidObjects’
other small fixes and improvements
price dropped from 45$ to 40$

how is the performance after the blood has flowed into place and it is just a static mark? What does it impact to have a bunch of AI around 20 units with blood on them? Is it a memory hog?

Hi,
after the simulation is done, there is close to no performance impact.
However if you have a bunch of simulators it can use quite a bit of gpu memory. Depending on the resolution of the fluid textures.

Each simulator uses 4 RenderTextures:

  1. contains the geometry data, wich is shared when multiple simulators use the same geometry (128bit per pixel)
  2. contains fluid data and the flow direction (128 bit per pixel)
  3. contains the moving fluid (32 bit per pixel)
  4. conatins the final fluid and normal data (32 bit per pixel)
    And two ComputeBuffers:
  5. filled with geometry data for recalculating the gravity map, wich is also shared between simulators wich use the same geometry (128 bit per triangle)
  6. filled with gravity directions in UV space (128 bit per triangle; I might be able to remove this in the next update)
    This means in the worst case each simulator uses (40 bytes per pixel + 32 bytes per triangle) of gpu memory.
    As long as you keep the fluid texture resolution reasonable (~512) it should be fine.

I am also thinking of adding a feature next update, wich lets you discard all data except the final fluid texture. So you can’t simulate any more, but the fluid is still shown.

Fluid Flow 2 has been released recently!

It is a complete rewrite of the original system, improving its usability, compatibility, and flexibility a lot.

Multicolored fluid/paint is now supported, and gravity maps can be updated in real-time, even for skinned meshes.
Additionally, Fluid Flow can now also be used as a basic real-time 3d texture painting asset, or for painting decals to skinned mesh renderers.

AssetStore: http://u3d.as/1vef

Hi, I’m wondering if this is fully compatible with URP? Also, are there cases where it would not work on a skinned mesh model?

Thanks, this looks very promising.

Hi,

yes, FluidFlow is basically independent of the rendering pipeline you are using. The actual painting and fluid simulation is handled outside of unity’s internal rendering loop, so it does not really matter if you are using URP, HDRP, etc.
So the package generates an internal texture independent of the rendering pipeline, however, you will need a shader, supported by your current rendering pipeline, in order to draw this texture onto your models.

There is a shadergraph shader for URP included with the asset, which supports this, and it would also not be hard to create one manually (check the corresponding chapter in the documentation).

And I am not aware of any problems with skinned mesh models. Skinned and non-skinned models are basically handled in the same way by FluidFlow, so there should not be any difference.

What is the proper way to go about adding RenderTargets to a FFCanvas at runtime? I tried making new “descriptors” every time one of my NPCs spawned in, but the decal I’m projecting never shows up on their mesh. If I add the same NPC’s renderers manually to the RenderTargets before hitting play then it works just fine, but that’s not ideal for runtime use.

1 Like

Hi, I am sorry for the late reply. Somehow, I did not receive a notification for this post… feel free to also contact me at mr3d.cs@gmail.com if I do not respond within 2-3 business days.

If you alter the RenderTarget/TextureChannel -Descriptors at runtime, you will have to reinitialize the FFCanvas.
This will allocate the necessary RenderTexture resources and assign the material properties of the renderers.
However, this will clear all the fluid/paint currently added to the FFCanvas.

What you probably want to do, is adding a FFCanvas component to each NPC, so the required resources are allocated for each NPC instance.
In general, a single FFCanvas component is intended to handle one ‘object’ (e.g. the player character). The multiple rendertarget slots are intended for cases, where this ‘object’ consists of multiple (Skinned)MeshRenderers.

I hope this clears thing up a bit.
Christian

Heya,
first of all I want to thank you for this well-made asset. It’s really high quality.

However, I’m having a really weird issue. Everything works and looks fine in the unity editor, but as soon as I make a build, the fluid simulation is frozen (tested with every update method and confirmed via debug that the update is called in the build (calling Fluid.Simulate()).

I’ve tested multiple things like a different renderer DX11/Vulkan, as well as different formats for the texture, but nothing seems to work.

Here is the weirdest thing: When I attach Unity’s Frame-Debugger to the build and enable it (which pauses the frame), and then disable it again, it fixes the problem and fluid simulation is running. Obviously, this isn’t really a fix, but hopefully some hint on what is going wrong.

I’m suspecting that there is either something with RenderTextures or maybe with Shader compilation that is causing it.

My fluid setup is using one RenderTarget and one texture channel. In the editor, everything is working perfectly.

The unity version I’m using is 2021.3.11f1. I will try to debug this further but I would be thankful for any possible help.

Let me know if I can provide any more information.
Thank you,
schema

EDIT: After 9 hours, I have found the issue. I took the shaders apart one by one until I found the value that was causing the problem.
It’s not an issue in the asset, but it’s a problem that apparently was introduced into unity.

After building and testing over and over, narrowing down the possible area, it turned out that all shaders and render textures were fully functional in the build, however, one little thing wasn’t: unity_WorldTransformParams.w

The only hint of this value being messed up was on the unity Graphics github for Unity 2023, where I found the following code:

inline float GetOddNegativeScale()
{
    // FIXME: We should be able to just return unity_WorldTransformParams.w, but it is not
    // properly set at the moment, when doing ray-tracing; once this has been fixed in cpp,
    // we can revert back to the former implementation.
    return unity_WorldTransformParams.w >= 0.0 ? 1.0 : -1.0;
}

I was wondering if this already applies to Unity 2021, and it turned out that it very much was.
The value was just plain 0, which set the tangent space binormal to 0 in turn making all gravity 0 as well when normal maps were used.

Adding this function to the common shader include and then replacing unity_WorldTransformParams with the function in Gravity.shader completely fixed the issue (it comes at the cost of a branch, but as the comment says, it can be eventually reverted).

I’m not 100% sure what odd negative scale is exactly, but from what I gather it’s a really ugly workaround to avoid reverse polygons or something. I’ve also seem people calling the value obsolete, but I haven’t found any official source on that.

Anyway, I hope this helps should you encounter the issue eventually.
cheers,

  • schema
1 Like

Hello @schema_unity ,
that does sound like a really weird issue…

It might be related to an issue, that I thought I fixed some time ago, but it seems like I have never pushed the change to the store, as I am currently working on a bigger update which is not finished yet.

In the flow map generation shader, I am using unity_WorldTransformParams.w which seems to work fine in the editor, but in the build it is set to 0 outside of unity’s main rendering loop…
As in most cases, unity_WorldTransformParams.w should be 1 anyway, you can just remove it from the shaders…
I have attached a screenshot with the two occurrences.

Please let me know if the problem persists… I will push an update to the store asap…

Best regards
Christian

edit:
Seems like you have figured it out yourself, before I was able to respond. Thank you for your investigation, this github comment is very interesting!

As you have already mentioned, the ‘OddNegativeScale’ has something to do with flipped triangles.
From my understanding the value should be -1, if one, or all three, XYZ scaling factors of your model are negative.
This should basically never occur for player characters, but maybe when mirroring some assets…

Btw. the comparison should not cause a branch here and just do a conditional assignment, so it should not be a big problem.

1 Like

Fluid Flow v2.5 has just been released!

The main part of the update is a new particle-based simulation mode.
Apart from that most of the core systems have been reworked for better performance and usability.

> AssetStore <

Cheers
Christian

hi there! I have just started using this asset and I am already a big fan of it.
I’ve got one question though. Is it possible to render a single channel to another texture?
To give a bit of context:

  • I am trying to stick with default hdrp shaders and use fluid flow only for rendering static decals on skinned meshes (at least for now I don’t want to change to custom shaders).
  • I get basic color and normal map rendering working after setup
  • but because how HDRP/Lit is constructed it would be awesome if I could also write only alpha channel to mask texture as it is responsible for smoothnes and mask map have metalic, ao, detail mask & smoothness packed in respective channels. More details here: Mask and detail maps | High Definition RP | 14.0.11.

Is something like this impossible atm or am I missing something?

Hi, I am glad to hear you like it so far!
To be honest I have not really thought about this usecase before, but this definitely seems like a useful feature!

One possible workaround could be to add a 4-channel packed TextureChannel, and 4 additional 1-channel TextureChannels for metallic, ao, detail & smoothness. And then just write a very basic Blit-Shader, which packs the 4 single-channel textures into one after each change to the textures.
Something like this (I can send you a full shader if you want):

return float4(tex2D(_RedTex, i.uv).x, tex2D(_GreenTex, i.uv).x, tex2D(_BlueTex, i.uv).x, tex2D(_AlphaTex, i.uv).x);

However, this is obviously not a very efficient solution, as this basically doubles memory usage and adds an extra drawcall.

The best solution would be a new option in the draw methods, which allows you to mask which channels are affected by a given decal/brush. This requires some modifications to the package though.
I will look into this later today, but this should not take too long to add.
If you send me your email address, I can send you an updated package as soon as it is done…

Best regards
Christian

Thanks for the ideas! To be honest - if this is the feature that you could integrate - I’ll be happy to just wait for it. I still have to integrate FludFlow into my systems before I’ll dig into the FF itself.
If I can be any of assistance - just let me know, I can test some preview releases or something. I’ll dm you my email address.

1 Like

What are the difference between particle mode and texture mode? Like performance, limitations, etc.