Dynamic expressions
Expressions can also be used in combination with dynamics, i.e., particles. We distinguish two types of dynamic expressions: creation and runtime expressions. A creation expression executes when the particle is emitted. A runtime expression executes in all other frames.

Per particle attributes
Particles share a single particle shape node. As a result, particle object attributes do not distinguish between individual particles. However, there are also per particle attributes which allow you to set a unique value for each particle. A per particle attribute is a single attribute that allows for an entire list (array) of values, one per particle.

Age
In animation expressions, you can use frame and time to retrieve the current frame and time of an animation. In dynamic expressions, you can also use age to retrieve a particle's age, that is the time since the particle's birth.

Below we will create a smoke emitter where the smoke particles grow bigger as they get older, and die at a random age. We will make use of both creation and runtime expressions and also of per particle attributes.

Start by creating a new scene

Smoke emitter
Create an emitter (choose Particles → Create Emitter)

  • Rename it to smokeSource
  • Alter the attributes as follows
     
      Emittertype : Directional
      Rate : 50
      DirectionX : 0
      DirectionY : 1
      DirectionZ : 0
      Spread : 0.25
      Speed : 2

     
    Smoke particles
    Select the particles (use the Outliner or run the animation shortly)
  • Rename them to smokePart
  • Alter the attributes as follows

      Render Attributes .. Particle Render Type : Cloud
      Lifespan Attributes .. Lifespan Mode : lifespanPP only

    lifespanPP is a per particle (PP) attribute.

  • Add a creation expression to lifespanPP that determines the lifespan per particle. Use the function rand() as a random value generator to generate a random lifespan between 4 and 6 (seconds).

    lifespanPP = rand(4,6);

  • Add a radiusPP per particle attribute (choose Attributes → Add Attributes... → Particle)
  • Add a creation expression to radiusPP

    radiusPP = 0;

  • Add a runtime expression to radiusPP to alter the radius of the particle over its age, starting with a radius 0 at birth up to a radius 1 at death. This radius can be calculated as the ratio of the particle's age to its lifespan, or using the function linstep().

    radiusPP = linstep(0, lifespanPP, age);

    Now, start the animation

    Fading
    We will change the opacity of the particles such that they fade away rather than popping out.

  • Add a opacityPP per particle attribute (choose Add Dynamic Attributes → Opacity and select Add Per Particle Attribute)
  • Add a creation expression to opacityPP

    opacityPP = 1;

  • Add a runtime expression to opacityPP to alter the opacity of the particle over its age, starting with opacity 1 at half its lifespan up to opacity 0 at death. The function smoothstep() is similar to the function linstep() except that it provides a gradual start and end.

    opacityPP = 1 - smoothstep((lifespanPP * 0.5), lifespanPP, age);

    Start the animation in shaded mode

     

    All of these actions, including the creation of the dynamic expressions, can be performed by a script. For your information, this script is included here:

    file -f -new;
    emitter -name "smokeSource";
    // Result: smokeSource //
    setAttr smokeSource.emitterType 0; // Directional
    setAttr smokeSource.rate 50;
    setAttr smokeSource.directionX 0;
    setAttr smokeSource.directionY 1;
    setAttr smokeSource.directionZ 0;
    setAttr smokeSource.spread 0.25;
    setAttr smokeSource.speed 2;
    particle -name "smokePart";
    // Result: smokePart smokePartShape //
    connectDynamic -em smokeSource smokePart;
    // Result: smokePartShape //
    setAttr smokePartShape.particleRenderType 8; // Cloud
    setAttr smokePartShape.lifespanMode 3; // lifespanPP only
    addAttr -ln radiusPP -dt doubleArray smokePartShape;
    addAttr -ln opacityPP -dt doubleArray smokePartShape;
    dynExpression -s "lifespanPP = rand(4,6);\nradiusPP = 0;\nopacityPP = 1;" -c smokePartShape;
    dynExpression -s "radiusPP = linstep(0, lifespanPP, age);\nopacityPP = 1 - smoothstep((lifespanPP * 0.5), lifespanPP, age);" -r smokePartShape;