FleX and Multiple Fluids

Is FleX capable of simulating multiple fluids with different properties in a single simulation? I saw a YouTube video from 2014 where NVIDIA appeared to be showing that: https://youtu.be/1o0Nuq71gI4?t=1m33s

But with the FleX plugin for Unity at least, the fluid settings affect an entire container/solver at once. Is there an implementation that offers what I’m after, or is it actually a limitation of FleX still? It can be another engine, I’m just most familiar with Unity.

Cheers

Did you ever get any response on this and/or figure this out? I too am finding out something odd about the current Unity implementation. It would seem that if you have two containers in one Unity scene then only the particles from 1 container will render at a time. If you move out of the view frustum of the current drawing container’s particles but keep the container that is not drawing in your view frustum then that one will start rendering.

In the UE4 implementation, you can have many containers (which hold the primary particle’s liquid behavior properties for only particles created inside that container) and utilize the particle group number if you want particles of separate containers to collide.

In the current Unity version, if you turn on “draw particle” you will see that the same behaviors described above are true…with the exception that only 1 container’s particles will render at a time…but as first described…if you position the camera to exclude one container but keep the other container(s) not rendering within the camera’s view frustum then it will render (one of the containers not rendering will start rendering, but if you have like 4 containers and move the one currently rendering out of the camera’s view frustum but keep the other 3 inside it, then only 1 of the 3 will render).

Has anyone figured out how to get more than 1 container to render at the same time in the Unity version?

push

I am looking for a similar problem.
I have 2 Flex Containers that I need to collide against each other. At the moment the particles act as if the other particles do not exist. Do I have to register them to each other or anything?

Using Unreal Engine 4.19 build from github.

I did in the same container, just in Unity I created two Flex arrays, and tied them to different game objects, and the different weight. And it turned out that the lung went up in the tank.

Hi,
do you mind sharing some source code?
As far as I see it, the unreal Flex Plugin does not allow that, so I would like to see how the Flex API is used in Unity and try to figure out what to do in order to make this work.

Have you looked at the Assembly-CSharp.Player project under the Assets\NVIDIA\Flex\Actors and Assets\NVIDIA\Flex\Helpers folders?

Pretty much those are the core classes that you would want to look at to better understand how they tie together. Especially the FexActor.cs file that is the base class for all other FlexActor.cs files.

Pretty much, if you use the same FlexContainer (located in Assets\NVIDIA\Flex\Assets) you will be able to replicate most of what you might have seen in the demo’s.

The one rendering issue I was running into, I believe, has to do with the Assets\NVIDIA\Flex\Helpers\FlexScene.cs that handles only a single container. Look at the bottom of the FlexScene.cs file and note the private property member “FlexContainer m_container;”.

Then look at the Assets\NVIDIA\Flex\Helpers\FlexFluidRenderer.cs file and navigate down to the OnFlexUpdate method. It utilizes the containe (i.e. FlexContainer) instance assigned to the actor and updates the indices on each update:

    void OnFlexUpdate(FlexContainer.ParticleData _particleData)
    {
        if (m_actor && m_actor.container)
        {
            m_actor.container.AddFluidIndices(m_actor.indices, m_actor.indexCount);
        }
    }

So, without making major changes to and/or creating your own implementation based on the sample they provided you will be stuck with a single container that several FlexActor derived classes can reference, and as long as they reference the same container (and you have the collision flags set properly) you should see two different FlexActor’s particles interacting with one another.

If you want to review the code that handles the collisions and particle velocity adjustments then you should look at the Assets\NVIDIA\Flex\Helpers\FlexParticleController.cs file. Specifically you should review over the FlexParticleController.OnFlexUpdate method:

   void OnFlexUpdate(FlexContainer.ParticleData _particleData)
    {
        FlexActor actor = GetComponent<FlexActor>();
        if (actor is FlexSourceActor)
        {
            FlexSourceActor sourceActor = actor as FlexSourceActor;
            var main = m_particleSystem.main;
            float time = Time.time - Time.fixedTime;
            int[] indices = sourceActor.indices;
            int indexCount = sourceActor.indexCount;
            float[] ages = sourceActor.ages;
            m_particleSystem.Clear();
            m_particleSystem.Emit(indices.Length);
            if (m_particles.Length != indexCount) m_particles = new ParticleSystem.Particle[indexCount];
            float startLifetime = main.startLifetime.Evaluate(0);
            Color32 startColor = main.startColor.Evaluate(0);
            float startSize = main.startSize.Evaluate(0);
            for (int i = 0; i < indexCount; ++i)
            {
                ParticleSystem.Particle p = m_particles[i];
                p.velocity = _particleData.GetVelocity(indices[i]); ;
                p.position = (Vector3)_particleData.GetParticle(indices[i]) + p.velocity * (time - Time.fixedDeltaTime);
                p.remainingLifetime = ages[i] - time;
                p.startLifetime = startLifetime;
                p.startColor = startColor;
                p.startSize = startSize;
                m_particles[i] = p;
            }
            //m_particleSystem.SetParticles(m_particles, m_particles.Length);
        }
        else if (actor)
        {
            var main = m_particleSystem.main;
            float time = Time.time - Time.fixedTime;
            int[] indices = actor.indices;
            int indexCount = actor.indexCount;
            //m_particleSystem.Clear();
            //m_particleSystem.Emit(indices.Length);
            if (m_particles.Length != indexCount) m_particles = new ParticleSystem.Particle[indexCount];
            Color32 startColor = main.startColor.Evaluate(0);
            float startSize = main.startSize.Evaluate(0);
            for (int i = 0; i < indexCount; ++i)
            {
                ParticleSystem.Particle p = m_particles[i];
                p.velocity = _particleData.GetVelocity(indices[i]);
                p.position = (Vector3)_particleData.GetParticle(indices[i]) + p.velocity * (time - Time.fixedDeltaTime);
                p.remainingLifetime = m_particleSystem.main.startLifetime.Evaluate(0);
                p.startLifetime = p.remainingLifetime;
                p.startColor = startColor;
                p.startSize = startSize;
                m_particles[i] = p;
            }
            //m_particleSystem.SetParticles(m_particles, m_particles.Length);
        }
        m_particleSystem.SetParticles(m_particles, m_particles.Length);
    }

As you can see, this is where a lot of the “heavy lifting” for adjustments of collisions and velocities of each particle is handled. Once you have a good understanding of how all of these elements tie together you should be able to “make custom modifications”. However, you also need to understand that the Flex Unity Library doesn’t work well when compiled as a Windows Universal application. My current “best guess” is that Windows Universal does not fully implement D3D Shaders calls and some of those calls are required by the NVidia Flex library. So publishing a project using this (Flex) as a “Windows Store” application just doesn’t work and haven’t seen any changes. I discovered this by trying to deploy a Windows Universal version to Xbox One(i.e. Creators Club) and got all sorts of errors about the NVidia Flex shader making unsupported calls (don’t remember the exact errors at this point).

Anyway, that is a good start if you just want to play around with it… but don’t expect to use anything you create as a “final application”…unless you have an actual XBox Developer SDK which in that case you can compile a true Xbox Native application and that will provide the full support required by the Flex libraries.

Hope this helps,

-Noel

Thank you very much!
If I understand correctly, this is basically the same as in Unreal.
We have a Container, on each tick it first updates params, loads the particles and starts the gpu solver.
So every loaded particle uses the same params, therefor all Particles have the same size. (solid rest distance and collision distance)

So in order to get particles of different sizes they would have to be in different Container Instances(Unreal) and FlexContainers(Unity). The problem then is, that these Particles would not collide with each other. Am I correct or is there a way to set some link to the other Container like: Hey, GPU! When you do the collision of these particles, could you please consider those 50 000 particles of another container as well?

The Particle System has a p.startSize, but unfortunately that is not the physics size, that is just rendering size and indeed you could set a different Size for every particle.

Hello. At Unity, you don 't have to write any code for that. Creates a single container and multiple arrays for a single container. It 's like video, just a few arrays. For each array you create a separate actuator, each array can be given a material - color, transparency, etc., if I remember correctly, but also a kind of particle size. There are physics modifiers in the settings - mass, attraction force, etc. Unfortunately I am busy with others, but I myself watched just these lessons from the video, and I have already thought that it should be several arrays and actuators - game objects for one container.
As for the unreal ingine, it 's a lot more complicated, and I didn 't do anything about it.

1 Like

Yes to most of what you said with the exception of the particle sizes. Instead of me trying to explain how this all works from the GUI/Editor side (as hretgear was pointing out), you should take a look through their documentation regarding how they store the particle information:
https://docs.nvidia.com/gameworks/content/gameworkslibrary/physx/flex/manual.html#particles
Here you will find this:
" For each particle the basic dynamic quantities of position, velocity, and inverse mass are stored. The inverse mass is stored alongside the position, in the format [x, y, z, 1/m]

So the each particle has two VECTOR4 values and one INT value (the phase).

As hretgear points out, you can set the particle’s initial sizes in the container’s properties (but it helps to understand how they store the particle information to better understand how the GUI/Editor’s properties translate to the code side in the event you wanted to modify any of these elements “on the fly”).

Anyway, that should get you going.