Posted by: Jeff | 2013/11/18

FumeFX – Controllers

Here are some use-case examples of things that you could do with a feature in FumeFX that is probably one of the most under utilized – The Source Controllers.

Source Controllers

FumeFX Source Controllers

An excerpt from the FumeFX help docs:

Source Controllers give you more control over the values that a source in your simulation will apply to each voxel.  The different types of controllers help you to quickly establish a source’s linear dependence on various channels in the grid (smoke, fuel or temperature) or the distance from an object.

Note that a different flavor of Source Controllers can also be found in a FFX Particle SRC object, called Interpolation Controllers. It will only be available if you enable the AFC curve for a channel.

FFX Particle SRC Expression Controllers

Interpolation Controllers

You can access these just by Right+Clicking on the buttons found beside the spinners.  A menu (FIG 1.) will pop-up where the options will slightly vary depending on what Controller you invoked.

FIG 1.

* * * * * * * * * *


  1. Distance Based Emission
  2. Fuel by Velocity
  3. Custom Data via Particle Age
  4. Ground Dust

* * * * * * * * * *

1. Distance Based Emission

Distance Based Emission

In this example, I used an Object Distance Controller to control smoke emission from particles.
The scene is set to have stationary particles lying on the ground set to emit smoke based on the distance from the sphere if it is within 20 units.

Scene View

Scene View

Whenever the sphere comes within the 0.0 to 20.0 unit range, the controller will output an interpolated value ranging from 0.0 to 1.0 which it will then apply to the current particle smoke density (in this case, a value of 2.0).

Object Distance Dialog

Object Distance Dialog

As an example, if the animated sphere comes within 10 units from a particle, the controller would output a value of 0.5, multiplying that to my smoke density, resulting in 1.0.


In addition, since I was only emitting smoke (with velocity, fuel and temperature initially disabled), I chose to also enable a Controller for the temperate, which is simply set to a Voxel Smoke Controller. This way, whenever the simulation detects smoke density inside a voxel, it would set temperature values accordingly.

Max File: Object Distance File (22 kb)

Back to Examples

* * * * * * * * * *

2.  Fuel by Velocity

Fuel by Velocity

Fuel by Velocity

Flame is only generated by source objects producing a certain speed.

Setup Notes:

  • I used a single FFX Object Source containing all the dynamic boxes for emission.
  • I also used an Effector to detect velocities that are within a certain threshold. It is then set to output an interpolated multiplier from the detected values.
  • The Effector’s output is then plugged to the fuel.
    The result will produce less fuel on low velocity areas, and more fuel on higher velocity areas.
  • The boxes are constantly emitting temperature values in order for the grid to be generated adaptively, and thus also produce velocities.
  • The Source Controller I used is of course, an Effector Controller.

Max File: Fuel by Velocity (401 kb)

Back to Examples

* * * * * * * * * *

3.  Custom Data via Particle Age

Custom Data via Particle Age

Custom Data via Particle Age

Due to a current limitation in FumeFx in supporting Box#3/mParticles data directly, the setup employs a workaround in passing data from PFlow to FumeFX via the Particle Age Channel.

  1. Start by building this simple Particle Flow setup.

    Particle View

    Particle View

  2. Particles are birthed to a teapot’s surface.

    Teapot with Particles

    Teapot with Particles

  3. Build this Data Flow.
    Data View

    Data View

    1. The data flow starts by setting a lifespan of 100.
    2. Then it uses an external object to detect particles that are inside a volume – in this case, a Box.
    3. A filter is then used to send out a constant particle age data.
    4. The data will be 100 if the particles are inside the Box, 0 if not.
    5. These values represent the start and end of each particles’ lifespan.
  4. We then proceed to build a FFX grid. Set it to emit from a FFX Particle Src – choose our PF setup above for emission.
  5. In the FFX Particle Src paramters, under the Fuel channel, set the amount to -1 and enable the AFC curve.
    Fuel Channel

    Fuel Channel

    This is where our Data Flow would kick in. The curve right now would not matter, that is because we set the particle age values to only output the start and end of the particle lifespan. FumeFx will only read the start and end of the AFC curve. This let’s us switch between two amounts:

    • 100 if particles are inside the box.
    • -1 if particles are outside the box.

    * I set it to -1 so that it would also delete fuel in the voxels.

  6. Running the simulation, particles will only burn if they are inside the box.

Setup Notes:

  • The setup is somewhat limited, when using modified Particle Age, you will not be able to make use of other functions in fume that rely on that channel.
  • Ideally, you may also be able to use the Particle Velocity data to have 3 more float values to play with. But in order to properly utilize that without breaking your particle motion, you would have to review a box#3/mParticles example file called CollisionAsBody.  This basically lets you do some post work with your particles.
  • The sub operators defining the particle age values are animatable. This way, you can animate a more softer transition from one value to another. You just have to keep in mind that the particle age largely depends on the AFC curve in FumeFx.
  • There are others ways of achieving the above example, this setup simply shows an example workaround to work with Box#3/mParticles data 🙂

Here’s another variation where I’m emitting smoke, again on particles inside the volume:

Custom Smoke Emission

Custom Smoke Emission

Max File: Custom Data by Particle Age (23 kb)

Back to Examples

* * * * * * * * * *

4. Ground Dust

Ground Dust

Ground Dust

This approach is largely similar in the approach used at #2. But instead of setting temperature values for the whole FFX Object SRC, I added an Expression Controller to filter in voxels near the ground.

Expression Dialog

Expression Dialog

if( comp(vxPosWorld,2) < 4, 1, )

Expression breakdown:

  1. The expression uses the vxPosWorld function to query voxel positions in world space.
  2. Then I used the comp(v,i) function to get the z component of the vector position
    * note that indices are zero-based *
  3. Lastly, the resulting value is filtered by an if(c,t,f) function.
    If the z component is below a certain distance (in this case, 4 units)
    THEN output a value of 1.
    ELSE output a value of 0 if it is not.

These values are then used as a multiplier for the current channel value (in this case, a temperature amount of 300).

Result of Expression on Temperature Channel

Result of Expression on Temperature Channel

A small run-down on what happens when you start the sim:

  1. The effector would generate velocities based on the movement of the box. These velocities are there because we have temperature emitting from the object which incidentally grows the adaptive grid.
  2. The temperature emission is clamped near the ground using the Expression Controller.
  3. Then we use the detected velocities to generate the fuel – where the fuel simulation is set to eventually create smoke.

The advantage to doing this is that you can be sure to only generate smoke whenever your object is moving, and only if it is near the ground.

Additional Notes:

  • The simulation is set to be Boundless except for the ground (+Z only)
  • The Blocking Side is set to -Z to simulate an infinite ground plane.
  • Smoke and Temperature Dissipation is also increased so that the simulation won’t leave a very long trail.
  • The only caveat for now is that this setup won’t work on uneven terrain. >_< (I still have to test an idea I have in mind..)
Car Wheel Burnout

Car Wheel Burnout



Max Files:

Back to Examples

* * * * * * * * * *

Expression Functions List

Below are the Expression Functions you can use listed in table form for easier reference:

abs(x) absolute value of x
acos(x) arccosine of x
asin(x) arcsine of x
atan(x) arctangent of x
ceil(x) smallest integer greater then or equal to x
comp(v,i) i‘th component of v
cos(x) trigonometric cosine of x
cosh(x) hyperbolic cosine of x
degToRad(x) x converted from degrees to rad
e the constant x (2.71828…)
exp(x) e raised to the power x
floor(x) largest integer less then or equal to x
if(c,t,f) conditional: value is t if c is true, else value is f
length(v) length if v
ln(x) natural logarithm (base e) of x
log(x) common logarithm (base e) of x
max(x,y) maximum of x and y
min(x) minimum of x and y
mod(x) remainder of x divided by y
noise(x,y,z) 3D noise function
Page(x) particle age – Afterburn
PEdist(x) particle distance from emitter – Afterburn
pi(x) the constant pi (3.1415…)
pow(x,y) x raised to the power of y
PposL local particle position (vector) – Afterburn
PposW world particle position (vector) – Afterburn
Pvel particle velocity – Afterburn
radToDeg(x) x converted from radians to degrees
sin(x) trigonometric sine of x
sinh(x) hyperbolic sine of x
sqrt(x) square root of x
tan(x) trigonometric tangent of x
tanh(x) hyperbolic tangent of x
TPS number of ticks per second
unit(v) unit vector in the direction of v
vif(c,v1,v2) “vector if” – value is v1 if c is true, else v2
vxFuel Fume FX – fuel content of the voxel
vxPosLocal Fume Fx – local coordinates of the voxel
vxPosWorld Fume Fx – world coordinates of the voxel
vxSmoke Fume Fx – smoke content of the voxel
vxTemp Fume Fx – temparature of the voxel

Some notes on these functions:

  1. The functions vxFuel, vxPosLocal, vxPosWorld, vxSmoke, vxTemp are only available in Source Controllers.
  2. The functions Page, PEdist, PposL, PposW, Pvel are only available in Interpolation Controllers.
  3. Functions are case-sensitive
  4. Vector Indices are Zero Based.
  5. The result of the expression in Source Controllers is multiplied to the value set for the channel.
  6. The Function List dialog is modal – forcing you to close it prior to being able to write an expression.

Back to Examples



  1. Very cool RnD Jeff!

    • Thanks JBond!

  2. Нi, Jeff. Could you throw a scene with dust and it is not clear how you did it.

    • Sure thing, I’ll add those this week (or as soon as I free up some workload).

      • I would love that scene files too!

    • Scene files uploaded, saved down to max2010 : )

      • Thank you very much, Jeff!!!

  3. Thank you very much, Jeff!!! I’ll wait impatiently

  4. Thanks so much “Fuel by Velocity” was exactly what I have been looking for.

  5. Amazing stuff as always. Thank You

  6. amazing !

  7. Cool and very useful. Thanks a lot Jeff!

  8. Dammit Jeff November!? How did i missed this? Great work as always some solid ideas!

    • Haha thanks Johnny, I did not notice either!
      I’m looking at the stats for today, it suddenly bloated and majority of the referrers came from facebook.. I’m wondering which facebook group it came from 😀

  9. thks..for sharing…awesome stuff as always…, again.. thank you

  10. It is good to see someone else trying their hand at using expressions. I usually use an expression controller as I have better luck with that. The length(V) is great for emission by velocity.

  11. Thanks man!! Keep on 🙂

  12. Thanks a lot.

  13. Hey. I ve got a little probleme. In the beginning of the simulation i ve block/pixel for the smoke.Few frame after its become smooth. Any idea how that can be fix ? i tried to bump the quality but nothing change.


  14. Talk about the ground dust. sorry.

    • you probably have a very thick smoke density.

  15. this kind of effect

  16. thanks Jeff ! amazing tricks

  17. wow what a lesson thnx jeff……..i was searchin such kind of stuff but couldn’t get it ……… now my dumb brain will kick some experiment…….

  18. […] research in expressions. Thanks to Jeff Lim for awesome exploration. I trying make something like him but without pf tool boxes. Here a few […]

  19. Hi Jeff,

    These are really nice examples. I have recently started with Maya FumeFx and getting decent results… but really large cache files (like 20GB for a 70 frames )… is it normal or can this be optimized?

    What kinda cache file size you get?

    Cheers and thanks for sharing!

    • Hi Amit,

      File size largely depends on your Spacing (number of voxels) and the Channels (smoke, vel, etc..) that you are saving.

      So say you are simulating smoke, if you want a smaller cache file size, you would increase you spacing (to an amount acceptable to the quality that you need) to get a volume grid with lower voxel counts. Then choose whether you want to include velocity and/or other channels. Typically you may only want to save the smoke channel for your smoke. Only include velocity if you would use it later on down the pipeline.

      Also consider using the Post-Processing feature of fume, it helps to optimize/clean up the existing cache.

      I hope this helps 🙂

      • Thanks for responding quickly Jeff,

        I guess, saving velocities etc. may be the problem for smoke…
        Will try decreasing the spacing and adding WT later.


  20. thanks

  21. What parameter decides how fast smoke is hiding? Thanks!

    • Did you mean how fast it would fade out?
      IF so, you would need to play around the Dissipation parameters.

      • Thanks! Works

  22. Amazing stuffs Jeff…I’m working on a project that requires ground dust according to the motion of an animal, but like you mentioned above that system doesnt work with uneven terrain. Wanted to know If there’s any workaround for that. Thanks 🙂

    • Thanks Richard, I haven’t tested, but one of the ideas I had was to use pflow box3 to transfer color data to the mesh/terrain (as in the channel painting tutorial), then maybe use this to drive smoke emission for any geometry.
      Magma and/or stoke modifiers could also come in handy (if you have access to them) using their geometry nearest point detection operators.

Leave a Reply

Fill in your details below or click an icon to log in: Logo

You are commenting using your account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s


%d bloggers like this: