r1 - 09 Apr 2007 - 18:20:42 - MattEstelaYou are here: TWiki >  Maya Web > WebLeftBar > MayaAnimation > MayaBatchRenderOptions > MayaCloth > MayaFluids


Combining Oceans and Ponds for wake effects

Duncan via highend3d:

You can combine the ocean and dynamic pond by using a wake on the ocean. This creates a fluid texture displacement on top of the ocean. You could replace the fluid texture with a projection of your ramp ripple if desired. The key is to map the ocean wave height offset attribute with a 3D or projective texture.

Animating wind/wave direction

Duncan via highend3d:

The waves move in the wind direction, but if this direction is animated then the waves will shift about the origin( like rotating the ocean ). This is because the waves are not dynamic.. frames do not depend on previous frames. One could map the height offset of the ocean with a projected ocean texture. The projection could be animated in x and z. Changing the direction of this animation would be a bit like changing the wind direction, if this was really needed.

Fluid shader for planet atmosphere

Duncan via highend3d:

I've been able to get a pretty good self shadowed atmosphere with volume primitives.

On the sphere shape turn on "recieve shadows", but turn off "cast shadows". Enable volume samples override and set the volume samples to 4 with depthJitter ON. On the sphereFog node ake the volume fog color blue and the edgeDropoff around 0.08. (no incandescence)

Illuminated should be on with a lightScatter value around 0.6. On the light (use a tight spotlight, not a pointlight) turn on depth map shadows and turn off useMidDist and useAutoFocus, setting the focus to the cone angle, the filtersize to about 6 and the bias to around 0.001 (the bias setting is critical). A depth map resolution of around 1024 worked for me.

There are probably some other settings I've forgotten, but hopefully this will help.

Note that if desired one can also assign a fluid shader to a volume sphere shape, setting the edgeDropoff to sphere on the fluid. The fluid is better at handling self shadowing of the volume than the volume fog shader, although it is more complex to setup.

a bit later...

The basics for doing this with a fluid shader: Assign a fluid shader to the volume sphere shape. Make the dropoff shape = "sphere" and give it a very small amount of edge dropoff... the transparency should be moderately low.

Turn all grids off and make the opacity input "constant" To make it fast, you could turn off self shadowing on the fluid and make the color a blue to black ramp with colorInput = y gradient. The ramp should have a fairly sharp transition( daytime/nighttime). Also turn off "real lights" on the fluid. Then rotate the fluid node such that the gradient points towards your sun.. this way you fake the shadow line.

and a bit later again...

I just realized that for the workflow I described, one needs to rotate the volume sphere primitive, not the fluid shape( it would probably be useful to hide the fluid shape, as it does not render and may just be confusing ). Also one needs to make the fluid size attribute = 2 2 2. Play with the edgeDropoff, transparency, and volume sphere's scale to get the right effect.

Altering the windtunnel preset

Duncan via highend3d, someone asked how to make fat tracers for the windtunnel preset, here's his reply:

Change the expression in windTunnel.ma to the following and you can control the emission width using the tracers attribute:

float $vel = windTunnelShape.windSpeed;
int $tracers = windTunnelShape.tracers;
int $yres = windTunnelShape.resolutionH;
float $density = 3.0;
setFluidAttr -at velocity -xi 0 -vv $vel 0 0 windTunnelShape;
int $i;
if( $tracers > $yres ){
   $tracers = $yres;
int $startY = ($yres - $tracers)/2;
for($i = 0; $i < $tracers; $i++ ){
    int $yIndex = $startY + $i;
    setFluidAttr -at density -xi 0 -yi $yIndex -fv $density windTunnelShape;

Accurate lighting preview with fluids

Duncan via highend3d:

The shaded display of the fluid has a fixed light direction that goes exactly along a diagonal. This makes for very fast evaluation of the self shadowing. It is feasable to implement hardware shadowing that looks at the internal light direction( and potentially at scene lights ) although we have not yet implemented this functionality.

To interactively preview the true shadows you could use IPR with the fluid's shading quality attribute turned down.

Fluids for fog

Duncan via highend3d:

Incidentally another technique to create illuminated fog volumes is to use a fluid node. You may need a high fluid shading quality setting to capture the edges of a hard edges spotlight cone without noise(using a bit of penumbra to soften helps), although it is quite flexible and can handle volumetric illumination by all light types. The media can be shadowed and can as well cast raytrace shadows. The opacity integration will be more realistic than with light fog. However render times will generally be slower.

Note that the volume objects that light fog is assigned to can also be assigned a fluid shader. You can create volume primitive and assign a fluid shader to them. (the fog assigned by default to the volume primitives does not adaptively evaluate light inside the volume the way a fluid does, although one could use volume samples override on the shape to increase the depth samples instead of using a fluid)

In general one would not bother having any volume grids when using a fluid in this manner, one would simply use its volume shading abilities.

Adjusting the visible volume

Similar to using amplitude, clamp and offset values for a 2dnoise, I've found editing density scale and temperature scale are the 2 major values for adjusting what you see. They seem to be independant of the simulation, so you can sometimes correct a bad solve (to a point) by adjusting the density scale so that you have a good amount of volume, then the temperature scale to shade that volume correctly. Its important to have your fluid display setting 'as render', hard to see whats happening otherwise.


This is pretty exaggerated, over adjustment like this tends to turn fire sims into lava-lamp on acid. Small adjustments work quite well though.

I found this was a great way to fix that hands-emitting-fire shot on my reel. The flame would streak horribly for the opening fast move, but by keyframing density and temp scale, I could carve the fluid down so it looked appropriate, then scale it back up once his hands stopped moving.

Copy emitter attributes between scenes

I needed this, you might too. I had too many surface emitters with different values to try and rebuild them by hand, so this script copied those special attributes onto the shape. I then deleted the emitters, copied the shapes to a new scene, made the shapes new emitters, then ran the 2nd part of the script to copy those custom values back into the emitters.

global proc copyFluidAttrs() {
// read the custom turbulence and heat emission attrs from surface fluid emitters,
// store as custom attrs on the connected shape node
    string $shapes[] = `ls -sl`;
    for ($shape in $shapes) {
        string $gc[] = `listConnections -s 0 -d 1 -t geoConnector $shape`;
        string $fe[] = `listConnections -s 0 -d 1 -t fluidEmitter $gc[0]`;
        float $turbulence = `getAttr ($fe[0]+".turbulence")`;
        float $heat = `getAttr ($fe[0]+".fluidHeatEmission")`;

        addAttr -sn turb $shape;
        addAttr -sn heat $shape;

        setAttr ($shape+".turb") $turbulence;
        setAttr ($shape+".heat") $heat;

global proc setFluidAttrs() {
// reverse of above; copy shape custom attrs to fluidEmitters

    string $shapes[] = `ls -sl`;
    for ($shape in $shapes) {
        string $gc[] = `listConnections -s 0 -d 1 -t geoConnector $shape`;
        string $fe[] = `listConnections -s 0 -d 1 -t fluidEmitter $gc[0]`;
        float $turbulence = `getAttr ($shape+".turb")`;
        float $heat = `getAttr ($shape+".heat")`;

        setAttr ($fe[0]+".turbulence") $turbulence;
        setAttr ($fe[0]+".fluidHeatEmission") $heat;


  • Good intro tutorial, creating a nice fire sim from scratch: http://zgrachan.com/pages/part1.htm
  • Apparently increasing the velocity damping will make the sim more stable, especially if you're animating values like temperature or fuel. Unfortunately this can also make the sim look like its fire in honey. I've found setting your cache oversample to 2 or higher also helps the sim stay stable, and doesn't adversely affect the look. At the cost of longer solve times and bigger caches of course.

Make a lit torch react to motion

From this highend3d forum post:

You are probably better off with particles for this. However you could try creating a motion field(under fluids) with your torch and your fluid selected. Make the volume shape of the motion field a cube, set its attenuation to zero and set the motion field scale so that it is fully encompasses the fluid. Now you need to edit the motion field expression.. list expressions by name and edit expression1. The motion field pushes the wrong way for this, so you want to put a "-" in front of motionField1 on the last line. Hit the edit button to accept the edit. On your fluid node you should make all boundaries=NONE, as well as set the damp to a small value, say 0.02. On the node motionField1 under extra attributes there is an attribute "pushIntensity". Adjust this along with the fluid damp to get the right effect when the fluid moves. It will not work perfectly. Part of the difficulty is that the velocity has some persistance(the damp helps this a bit, but affects the look of the flow).

Control speed of fluid in XYZ

If you don't want the contents to move in X you could try setting the velocityScale X value to zero (and key it up when you want it to move ).

Omni directional emitter in Fluids

You may wish to use a volume emitter (shape=sphere) with density buoyancy set to zero. Temperature turbulence can work well for this fireball effects, however there was a bug (fixed in Maya6.0) where temperature turbulence was biased strongly along the positive diagonal.

Note that fluid cannot move directly outward in the fashion of an omni emitter. It is like a tank of incompressible water. Outward and inward motions would compress the fluid. This is confusing, but it is the way gas and water behave Gas is somewhat more compressible than water, but in many simulations this can be ignored. You could scale your volume emitter quickly at the start of the explosion to simulate a concentric burst(in an actual explosion a combination of fine scale turbulence, solid particle motion and compression waves in the gas would cause the puffball). The general turbulence can help add detail, although temperature based turbulence is generally better( if you have Maya6.0) You need to have a temperature grid and it is good to also have some temperature dissipation.

There are also some fluids presets for exploding fireballs, although these are done by keyframing textural attributes on the fluid rather than dynamic simulation(these presets have no grids).

-Duncan Brinsmead via the highend3d list

Render particles with fluid shader

Interesting thread from highend3d here. And here, but easier still is to use Peter Shipkov's afterburn script.

Forces on fluids vs builtin fluid attributes

From here.

I used to animate with fields, but didn't get very good results. I felt like I was "forceing" the fluids around instead of letting the sim do it for me. I know you directed this at Ducan, I can get you started by explaining the gist of the internal animation with fluids.

All the animation controls are in 2 places: Dynamic Simulation(sets the world rules), and Content Details (sets how the specific fluid will animate). It's all about temp and density...

Density is what you see. So you can give it a + bouyancy and make it go up. - makes it go down.

It you add temp (what you can't see) and give them conflicting bouyancys then when the temp disapates the density falls (or rises). If you give temp a high diffusion then the fluid will plume out, high dissapation the density bouyancy will take over because the temp dies out. High temp bouyancy and you'll get a mushroom cloud effect. Anyway there's a lot along these lines...

It take a good amount of playing before you get it, study the fluid examples in the visor, they are animated this way. They're set up can teach you different methodes. Hope this helps you get started,


Emit 2d fluid from image sequence

From here:

Here is a little expression that gets the alpha from a file texture node "file1" and adds this every frame to the fluid node "fluidShape1". It samples the file node based on the fluid resolution. If you want it to use an image sequence, simply turn on "useImageSequence" on the file texture node. To use color instead of alpha you can use RGB instead of A in the colorAtPoint call. Then in the loop you need to get the r,g and b values from the array, incrementing the index after each.


int $nx = fluidShape1.resolutionW;
int $ny = fluidShape1.resolutionH;

int $i, $j;
float $colorArray[] = `colorAtPoint -o A -su $nx -sv $ny file1`;
int $index = 0;
for( $i = 0; $i < $nx; $i++ ){
for( $j = 0; $j < $ny; $j++ ){
setFluidAttr -at "density" -ad -fv ($colorArray[$index]) -xi $i -yi $j fluidShape1;

Comp and render passes help with fluidFx

Someone needed to break an ocean render into several passes so they could have an object half-submerged, here's Duncan's advice:

I think your problem is that there are two components to the water shading

  1. The surface reflection, which is basically like an incandescence.. it is simply added to whatever is seen throught the water.
  2. The diffuse scattered light by the water(water color value). This is modulated by the transparency of the water, and is the combined translucent and diffuse color.

Presumably you get roughly the desired look in a combined render, but wish to break up for post tweaking. To composite this cleanly you may need an extra render of the water surface. Exactly how you break this up depends in part on what you intend to do in post.

One method would be:

  1. Render of fully shaded object with black ocean. Color=black, transparency = 1.0, zero specular, black env ramp, no reflections on ocean
  2. Pure white surfaceShader on object with the same black ocean, but with the desired transparency setting.
  3. Hide object, render of diffuse ocean scattering: zero specular, black envRamp, raytracing off
  4. Show object with black surfaceShader, render incandescent ocean elements: specularity, env ramp, raytraced reflections, but black ocean color.

To combine the images(number refers to pass above): outColor = color2 * color1 + color3 * (1-color1) + color4

(I've not tested this but hopefully it will work) Sorry if this seems overly complex. There are simpler methods. This allows you to, for example, scale the brightness of pass 2 to control the falloff of transparency with depth by the ocean.
-- Duncan Brinsmead - 16 June 2004

Ocean Wakes and how to make em dance

I had some grief when the wakes I created gave me no foam, I searched around and found this gem below. - DeanErvik?

When one initially creates an ocean wake the wake object itself can emit foam into the foam grid(so long as foam emission is not zero when one creates the wake), but the peaking waves themselves will not generate foam. There are a few ways one can handle this. The ocean shader has controls for display of foam on peaked waves, but it does not recognize the additional waves created from wakes(fluid textures). One can remedy this by connecting the outAlpha of the wake texture to the foam attribute on the ocean shader( note that the resulting foam on the wake will not display on the ocean preview plane. Also you do not need a foam fluid for this ). To set this up first create a setRange utility in the hypershade window then do the following connections:

connectAttr -f oceanWakeTexture1.outAlpha setRange1.valueX;
connectAttr -f setRange1.outValueX oceanShader1.foamEmission;

The setRange is to remap the output of the fluid into a better range for the foam attribute. On the set range you might try the following values: oldMinX = -1 oldMaxX = 1 minX = -2 maxX = 2

Also set the foamThreshold on the ocean shader to something like 0.545

If you don't see any foam on your wakes try a min/max X value of something like -4,4 The larger this spread the more contrasty and pronounced the foam will be. To also have foam appear on ocean waves(non-wake waves) make the minX value a bit larger, i.e -1,2.

If you want the generated foam to be more dynamic you could use get and setFluidAttr calls in an expression to walk the array of points in both the foam fluid texture and the wake fluid texture, adding heat to the foam texture when the wake fluid texture density is over a certain threshold.

One thing that can be quite effective is to create particles from peaking points on the surface and then when the particles collide with the surface( and are also moving downward ) to kill the particle and add a bit of heat(foam) into the foam fluid texture.

Here is some info on emitting particles from peaking waves on the ocean.. note that instead of emitting from the ocean surface, you could emit from a plane grouped with your boat, if you only want particles created from the boat wake. The y position of the emitted particles is controlled by the create expression, which looks at the ocean surface, rather than using the y from the plane position.

You can use the command colorAtPoint to get the ocean height at a given xz location. You can use this to initialize the position of your particles in a creation function.

Step one.. make your ocean surface( the large circular nurbs ) a particle emitter with per particle lifespan. (note that you can really use anything as a particle emitter, as long as it distributes them in xz the way you want)

Step two: make the following particle creation expression:

vector $pos = particleShape1.position;
float $px = $pos.x;
float $pz = $pos.z;
float $disp[] = `colorAtPoint -u $px -v $pz oceanShader1`;
float $py = $disp[0];
float $sprayHeight= 0.0;

if( $py > $sprayHeight ){
   // set the y height to match the water
   particleShape1.position=<<$pos.x, $py, $pos.z>>; 
   particleShape1.lifespanPP = rand(1) + 0.2;
} else {
   particleShape1.lifespanPP = 0;

This will make the particles emit at the correct ocean height, and will kill all those below zero in y. Adjust the sprayHeight value for the height above which you want spray.

Note that a trick used in perfect storm was to create a force that acted vertically on the particles, sucking them up and down with the waves( for large waves it will look fake if you don't do this ). A way to do this might be to create a fluid node with a static velocity grid and use this as a force on your particles. Use setFluidAttr to set the velocity values based on the current ocean elevation( derived using colorAtPoint ). A simpler method might be to have a runtime expression that pushes the particles down if the ocean is below zero and pushes them up if above zero,varying the amount of push based on the height of the particles( high particles get more down push, low particles get more up push ). A method that looked at the current vertical velocity of the ocean might work better, however. If you want to get the velocity of the ocean, one trick is to create a duplicate oceanShader, only with the time input offset a little bit. Now you can do the difference between the height of the two ocean shaders to get the velocity.

Here is a runtime expression that does the sucking effect. It makes the foam flow over the waves nicely and keeps the particles above the water. (you could evaluate neighbor points and do surfing of foam down the slope of the wave if you want to get fancy )

vector $pos = particleShape1.position;
float $px = $pos.x;
float $pz = $pos.z;
float $disp[] = `colorAtPoint -u $px -v $pz oceanShader1`;
float $py = $disp[0];
float $yDiff = $py - $pos.y;
float $suckForce = .05;
float $minElevation = 0.05;// min height of foam above water.
$py = $pos.y + $yDiff * $suckForce;

if( $py < $disp[0] + $minElevation){
   $py = $disp[0] + $minElevation;

particleShape1.position=<<$pos.x, $py, $pos.z>>;

If you wanted you could kill the particle when it goes below the water by making its lifespan -1 and add some heat into the foam texture at that point. To find the coordinate of the fluid at that point you can use the fluidVoxelInfo command, then use setFluidAttr to add in the heat.

I hope this helps.


And then this post followed soon after:

Don't run the wake texture through a setRange( it will not longer appear on the heightfield preview ). Instead adjust the alpha gain on the wake texture.

-- DeanErvik? - 01 Aug 2004

More Ocean Wake Advice

I wasn't getting white wash wakes when I should have been. - DeanErvik?

(make sure you have foam emission set to something other than 0 BEFORE you add any wakes, try .275! A foam threshold of around .534 worked well for me, it takes a lot of tuning. Also make sure to use the create wake option box and enter a foam emmision value there too, as you make the wake.)

The saga continues...

I had made a wake , it worked pretty well. I then made copies of this one, they did not produce any foam, only wakes, regardless of how I copied them. They were not in the 2D fluid loop, so to speak. Those vital fluid connecttions could not be maintained.

So the rule is: Make a new wake from the fluid menu afresh each time you need a new one and then set all the attributes to the first best one in the spreadsheet editor, if appropriate.

Also I must add that the whiteness that is first created is actually a predefined 2D fractal that has its color gain maxxed out so it looks plain white, reduce color Gain (or is it Mult?) to black or near black to get a fractal revealed and ready to tweak. Once your set up is looking very close to finished try tweaking up the alpha settings on the fractal or maybe try increasing the the color gain past 1, these kinds of tweaks should help amplify (and therefore increase the spread of) your white wash from the wakes.

Ideally a supercomputer would be nice to tweak wake settings on in real time.

Also mentally get to grips with the way foam is made from a 2D fluid having wakes punched through it and creating fringed holes that act as the matte to reveal the fractal. Let me explain another way: Imagine a perfectly still solid (black) film of smoke hanging in the air above you like a plain. You punch through it wearing boxing gloves. The active and messy hole you create shows up as white instead of black. This white "gash" or "hole" is where a 2D fractal is revealed. This "artwork" is them mapped onto a dynamically animated water surface that just happens to be buldging in similar places as the foam map is placed, bingo!

Happy sailing.

Topic attachments
I Attachment Action Size Date Who Comment
jpgjpg fluidAdjust.jpg manage 32.6 K 09 Apr 2007 - 18:20 MattEstela  
Edit | WYSIWYG | Attach | Printable | Raw View | Backlinks: Web, All Webs | History: r1 | More topic actions
Powered by TWiki
This site is powered by the TWiki collaboration platformCopyright © by the contributing authors. All material on this collaboration platform is the property of the contributing authors.
Ideas, requests, problems regarding TWiki? Send feedback