PhysX Liquids Simulation
by Tobias B. · in Torque 3D Professional · 02/05/2010 (3:36 pm) · 7 replies
Hi,
I'm thinking about using a liquid simulation in T3D. It should consist of a moving tube delivering mud or other liquids filling a basin.
I'm having no experience using PhysX in T3D. If I want to use the liquids physics capabilities of PhysX - do I have to implement everything from scratch, or does the current implementation allow me to easily get access to the liquid simulation features PhysX provides?
Thanks a lot for any hint,
Tobias
I'm thinking about using a liquid simulation in T3D. It should consist of a moving tube delivering mud or other liquids filling a basin.
I'm having no experience using PhysX in T3D. If I want to use the liquids physics capabilities of PhysX - do I have to implement everything from scratch, or does the current implementation allow me to easily get access to the liquid simulation features PhysX provides?
Thanks a lot for any hint,
Tobias
#2
Okay - that means, even if I get access to the physical simulation, I still have to care for the rendering of many thousands of spheres. That sounds like a lot of work...
02/06/2010 (8:53 am)
Thanks!Okay - that means, even if I get access to the physical simulation, I still have to care for the rendering of many thousands of spheres. That sounds like a lot of work...
#3
I have gotten several thousands of point-lights running as a fluid simulation, and that is without instancing (though I suspect that I am approaching being blend-bound).
02/06/2010 (2:06 pm)
A solution (hah) to this problem does exist, but it may not be something that you can wait for.I have gotten several thousands of point-lights running as a fluid simulation, and that is without instancing (though I suspect that I am approaching being blend-bound).
#4
The geometry approach
Use marching cubes or some similar algorithm to generate geometry from a discreet 3D dataset (aka: a 3D grid filled by your liquid particles).
The fancy shader approach
For each liquid particle, draw a screen aligned quad (like a normal particle) with a specially-prepared texture that contains a sphere's normal and depth values (an RGBA texture with normals in RGB and depth in Alpha will do).
Draw them to a 64-bit render target (R16B16G16A16), writing the normals to RGB and the depth (subtract the sphere-texture depth from the actual particle screen-space depth) to Alpha. Don't use blending. Since you're already using the alpha for depth, you can mask the spheres in the shader by checking the fragment distance to the particle center. Also, remember to output depth values to the depth buffer and use depth-testing.
If you did everything correctly, you'll be drawing perfectly round spheres which properly intersect each other using only 2D quads. And you'll have their normals and depth values in a texture, which you can use to render their volume with correct deferred lighting and even refraction effects. If you apply a custom blur algorithm to the normals and depth texture you can "melt" the spheres together and get rid of "this is just a bunch of spheres clipping through each other" look.
02/06/2010 (9:37 pm)
To render the liquid, you have two approaches:The geometry approach
Use marching cubes or some similar algorithm to generate geometry from a discreet 3D dataset (aka: a 3D grid filled by your liquid particles).
The fancy shader approach
For each liquid particle, draw a screen aligned quad (like a normal particle) with a specially-prepared texture that contains a sphere's normal and depth values (an RGBA texture with normals in RGB and depth in Alpha will do).
Draw them to a 64-bit render target (R16B16G16A16), writing the normals to RGB and the depth (subtract the sphere-texture depth from the actual particle screen-space depth) to Alpha. Don't use blending. Since you're already using the alpha for depth, you can mask the spheres in the shader by checking the fragment distance to the particle center. Also, remember to output depth values to the depth buffer and use depth-testing.
If you did everything correctly, you'll be drawing perfectly round spheres which properly intersect each other using only 2D quads. And you'll have their normals and depth values in a texture, which you can use to render their volume with correct deferred lighting and even refraction effects. If you apply a custom blur algorithm to the normals and depth texture you can "melt" the spheres together and get rid of "this is just a bunch of spheres clipping through each other" look.
#5
I am trying to implement screen space meshes for the now working PxFluid, the docs I have all point at either marching cubes or marching squares, but I cant get my head around how to do it,
do you have any pointers or ideas to implement this?
or anyone else? Pat? you know about this stuff, no?
I will release the new PxFluid files to all source owners as soon as its all done, and this is the last bit to do.
thanks to anyone who can help on this.
cheers
01/02/2011 (12:01 am)
@Manoel,I am trying to implement screen space meshes for the now working PxFluid, the docs I have all point at either marching cubes or marching squares, but I cant get my head around how to do it,
do you have any pointers or ideas to implement this?
or anyone else? Pat? you know about this stuff, no?
I will release the new PxFluid files to all source owners as soon as its all done, and this is the last bit to do.
thanks to anyone who can help on this.
cheers
#6
But I'm not sure this approach would suit you, since you seem to be modeling the fluid as particles, which have free-form positions. You'd need to "render" the particles to a volume grid first.
Ah, wait, you *can* generate marching cubes without a volume grid: all you need is a function that takes a Point3F and returns true/false if it's in solid/empty space. That's how metaballs work (it uses the inverse of the sum of distances to all points, I think). Check if PxFluid offers some method to do this for you.
01/04/2011 (9:53 pm)
I never implemented marching cubes/squares myself, I only looked into the algorithm a while ago. AFAIK, it seems easiest to implement when you have a regular grid of 3D data (like a black&white 3D texture). You basically iterate over the grid, check which neighbors are occupied/empty and use that information to lookup a polygonal shape from a table. If all neighbors are filled/empty, no shape is used.But I'm not sure this approach would suit you, since you seem to be modeling the fluid as particles, which have free-form positions. You'd need to "render" the particles to a volume grid first.
Ah, wait, you *can* generate marching cubes without a volume grid: all you need is a function that takes a Point3F and returns true/false if it's in solid/empty space. That's how metaballs work (it uses the inverse of the sum of distances to all points, I think). Check if PxFluid offers some method to do this for you.
#7
this is my render paticle, it uses a standard vBuff, as you see,
with point support.
the fluid is a ShapeBase child,
so I believe supports customMaterials?
which means that the shader is now the key,
the verts are there, the shader can get the points, and create the "mesh"....
and thats where I am stalled, my shading skills(and my coding skills too, for that matter) are really not up to finishing this easily.
again, the files are available if anyone has the ability to complete this.
its an addition that is really very cheap, physics wise, and is really very usefull, makes awesome smoke and fire in addition to liquid,
you can even make jello and clay!
01/04/2011 (11:21 pm)
there wasnt, thats what I added to get rendering.this is my render paticle, it uses a standard vBuff, as you see,
with point support.
void PxFluid::renderParticle(Point3F &pos)
{
PROFILE_START(PxFluid_renderParticle);
mVertBuff.set(GFX, 4, GFXBufferTypeVolatile);
mVertBuff.lock();
MatrixF camView = GFX->getWorldMatrix();
camView.transpose();
for(int i = 0; i < 4; i++)
{
mVertBuff[i].point = basePoints[i]*5;
camView.mulV( mVertBuff[i].point );
mVertBuff[i].point += pos;
mVertBuff[i].texCoord = texCoords[i];
}
mVertBuff.unlock();
GFX->setTexture(0,mParticleTexture);
GFX->setVertexBuffer( mVertBuff );
GFX->drawPrimitive( GFXTriangleStrip, 0, 2 );
PROFILE_END();
}the fluid is a ShapeBase child,
so I believe supports customMaterials?
which means that the shader is now the key,
the verts are there, the shader can get the points, and create the "mesh"....
and thats where I am stalled, my shading skills(and my coding skills too, for that matter) are really not up to finishing this easily.
again, the files are available if anyone has the ability to complete this.
its an addition that is really very cheap, physics wise, and is really very usefull, makes awesome smoke and fire in addition to liquid,
you can even make jello and clay!
Torque Owner Henry Todd
Atomic Walrus
You have to then figure out how to actually make this look like liquid, as PhysX doesn't include rendering stuff. The easiest method is probably to render particles for each liquid element instead of geometry.
That said, there is not a native Torque object for liquids, but it would be easy to expand the current integration to access the PhysX liquid. I would not, however, attempt to network these various particles considering their huge numbers! This would effectively be a client-only effect, though you could network the state of the liquid "emitter" itself.