Painting With Particles
By Eric Keller
copyright 2007 Bloopatone

I developed the technique described in this tutorial as a way to control the radius of blobby surface particles painted on a surface via keyframes and some custom controls. Being able to access these attributes using the graph editor is very handy, especially when you need to constantly revise and refine the effect. The end result is a system where particles grow across a surface according to the way they have been painted on the surface using the particle tool in sketch mode. No emitters are involved.

The first section describes the workflow for setting up the expressions and controls on a single particle object. The second section takes you through the process of writing a MEL script which can automate the setup on several particle objects at once. Using the script reduces the set up to a click of a shelf button freeing you to be as creative as you want to be as you paint the particles.

Check out this quicktime of the effect in action:

Over view of The particle Effect Workflow:

This particlular workflow is designed to easily set up a particle system (a blobby surface particle in this case) so that it will grow along a surface. The ideas is that you take a surface (NURBS, or polygon) make it live and then use the particle tool in sketch mode to paint the particles however you'd like. The particle growth effect is dependent on the each particle's id number so how you paint the particles determines how the particles will grow. Once you've painted the particles where you want them you set the particles to blobby surface and then add some custom attributes and expressions. These expressions control the per particle radius of each particle. When you keyframe a custom (scalar) attribute on the particle node, the particles grow (increase their per-particle radius) along your painted paths based on the keys set on the custom attribute. The advantage of this is that you can easily retime and refine the way they grow on the graph editor. This gives you a high level of control so that you can tune the effect quickly and easily using just a few keyframes on some custom controls.

Part One: Setting up the Expressions

Step 1: Create a NURBS or polygon surface. For my example I'm using a generic polygon head I created. the whole thing is one object - eyes and all (figure 1). Select your object and make it "live" so that you can paint particles on it. Modify>Make Live.

Figure 1: The polygon head model.

Step 2: Switch to the Dynamics menu set and choose the Particle Tool (Particles>Particle Tool>Options). Open the options box and turn sketch particles on. Adjust the radius and sketch interval so that you get a nice dense clump of particles when you paint on the surface. You may need to experiment a little before you get the right brush size (figure 2).

Figure 2: Use the particle tool to sketch on the live model:

<<You can't really "undo" while the particle tool is active. If you paint something you don't like, just hit the enter key to complete the tool, delete the particle object you just made, adjust the partcile tool settings and try again. You can adjust the brush settings while the particle tool is active which means you can increase and decrease the brush radius while painting away.>>

Step 3: Paint some strokes on the surface. Keep in mind that the order in which the particles are created with the stroke is the order in which they will grow. You can use this to your advantage to make some interesting effects. branch out from the center to create the look of a spreading growth. Add a few long, sudden strokes mixed in with short dense ones to vary the way in which the particles spread.

Step 4: Once you are satisfied with the particles you've painted, hit the enter key to complete the tool. Don't overdo the painting, the more particles you paint, the heavier the scene will become. To"unlive" the surface you just select the object and choose Modify>Make Not Live.

Step 5: Rename the particle object "crawler1". Select the crawler1 object, open its attribute editor. On the crawlerShape1 tab look under the render attributes abd set the Particle Render Type to "Blobby Surface".

Step 6: Scroll down in the Attribute Editor to the Per Particle (Array) Attributes. The first attribute we'll add will control the rate of growth of the particles along the painted path. Under the Add Dynamic Attributes rollout, hit the General button. (figure 3).

Figure 3: The Per-Particle Array Attributes for the crawler1 shape are found in the attribute editor:

Step 7: In the panel set the name of the attribute to growMe. Set the type to float and make sure its a scalar attribute. This means it will be added to the particle's shape node, it will not be a per-particle attribute. Dynamics Weight and Conserve are a couple examples of scalar attributew (figure 4).

Figure 4: The custom growMe attribute is added as a scalar, float, attribute.

Step 8: Hit the General button under Add Dynamic Attributes again. In the pop-up window, switch to the particle tab. From the list select radiusPP and add it to the particle object (figure 5).

Figure 5: From the Particle Tab, select the radiusPP attribute.

Step 9: Hit the General button again and switch to the first tab. In the name field type maxSize. Make the attribute a float and set it to a per-particle array attribute.

Step 10: Add another float, per-particle attribute and name it growRate.

<<The new per particle attributes should show up in the Per Particle (Array) Attributes list. If they don't, hit the Load Attributes button at the bottom of the Attribute Editor. growMe should not be in the Per Particle (Array) Attributes list. You can find it under the Extra Attributes roll out at the bottom of the attribute editor (figure 6).>>

Figure 6: The new attributes are added to the list of array attributes. If they don't show up, Hit the Load Attributes buttona at the bottom of the editor

Step 11:  Next we'll add some creation expressions to establish the initial settings at birth (or in this case the start of the animation) for each particle. What we want is for each particle to have a random size as well as a random rate of growth. The radius per particle attribute will be animated so we can't just set that to a random number. Instead we'll establish a maximum size for each particle and randomize this - hence the maxSize per particle attribute we made in step 9. Right-click in the field next to the maxSize attribute and choose creation expression. In the expression editor add the following:

maxSize=rand(0.1,0.8);

This will ensure that each particle achieves a maximum size somewhere between 0.1 and 0.8. You may need to adjust these numbers depending on your scene size. a radiusPP of 1 means the radius of the particle will be equal to one grid unit.

Step 12: We'll be using a number of random numbers in these expressions so let's establish a per partcle seed for the random numbers. This means that each time we run the scene we get the same random numbers. to do this add a line before the maxSize expression:

seed(particleId);

This sets the random seed for each particle equal to the particle's Id number. If someone else rune the scene on their machine their results will be the same because the random numbers will be genrated frm the same seed value. Its not absolutely necessary, but its a good practice to keep (doesn't mean you can skip making a particle cache though).

Step 13: Lets add another expression to randomize the rate of growth for each particle (figure 7):

growRate=rand(.01,.05);

The larger these numbers, the faster the particles will grow. Alternatively you could make the rate of growth related to maxSize so that larger particles grow slower. Try something like:

growRate=0.1*(1/maxSize);

Figure 7: The creation attributes in the expression editor.

Step 14: Add a line to initialize the radiusPP so that the particles don't blink on and off at the start of the animation:

radiusPP=0;

Step 14: Next we'll add the runtime expressions, this is where the magic happens. Its also pretty darned simple. Basically we have a conditional statement saying that if the particle's ID number is greater than the growMe attribute (the scalar attribute we added to the particle shpae node) then set the radiusPP attribute to 0, else set the radiusPP equal to the radiusPP + the growRate attribute. We the clamp this value so that the radiusPP is not able to go past the maxSize value. Make sure you've applied the creation expressions and then switch to the runtime before dynamics expressions window in the expression editor and add the following (figure 8):

if (particleId>growMe){
    radiusPP=0;
}
else
{
    radiusPP=clamp(0,maxSize,radiusPP+growRate):
}

Figure 8: The runtime expressions in the expression editor.

Step 15: Apply the runtime expressions, switch to the perspective window and play the animation. Nothing happens (well, actually you may have one lonely particle growing all by itslef, we'll fix this in a moment). This is because we need to set some keyframes on the growMe attribute. How do we determine what values to set growMe to (between zero and what?). Since the expression is based on the particleId number we just need to find out how many particles are in this group. We can find the count attribute in the attribute editor for the particle shape and use that number. Lets say the value is 3620 (figure 9). Ok, set the timeline to frame 1 and set the growMe attrribute to 0 (you can find the growMe attribute in the channel box for crawler1 under the shape attributes, see figure 10). Move the timeline to frame 200. set growMe to 3620 (or whatever the count value for your particle is) and set another keyframe.

Figure 9: The particle count can be found in the attribute editor.

Figure 10: The growMe attribute can be found in the channle box for the crawler1 object.

Step 16: Play the animation. now you should see the particles grow along the path you painted. Pretty neat (figure 11). You can lower the growRate range in the creation expresions to change the way it looks as it grows. If you have a lot of particles growing over a short time you may want to lower the range to something like 0.005 and 0.03.

Figure 11: The blobby surfaces now grow along the surface.

Lets add another control to sweeten it just a little more...

 Step 17: Create a locator and name it particleScaleMult. Add a custom float attribute to the locator and name it scaleUp (to do this, open the attribute editor for the locator and, from the top menu of the editor, choose Attributes>Add Attributes...). This attribute will be used to as a keyframeable multiplier to the maxSize attribute on the particle. I'm using a locator so that the same control can easily be added to multiple particle objects. It's just a way to oganize the scene really (figure 12).

Figure 12: The scaleUp attribute is added to the particleScaleMult locator.

Step 18: Open up the expression editor for the crawler1 object and switch to the runtime expressions. Add this line above the conditional expressions (figure 13):

maxSize=maxSize*particleScaleMult.scaleup;

Figure 13: The maxSize attribute is edited in the expression editor.

Step 19: Apply the expression ans select the particleScaleMult locator. Set its scaleUp attribute to 1. Play the animation to frame 180 and set a key on the scaleUp attribute. 

Step 20: Set the frame to 200 and set the scaleUp attribute to 1.5. set another key.

Step 21: Open the graph editor and edit the keyframe curve on scaleUp so that it starts flat and then ramps up sharply right before the end.

Step 22: Play the animation. You'll se the particles grow along the path, then at the end they will all start to grow together quickly. you can create some cool Akira-like anime effects with this kind of control. Alternatively if you wanted to kill all the particles at once you could scale down the particles by reducing the scaleUp control.

Step 23: Select the crawler1 particle object and open the graph editor. Select the crawlerShape1.GrowMe attribute and adjust its keyframes to make the growth of the particles a little more interesting (figure 14).

Figure 14: The keys on the scaleUp attribute are edited on the graph editor to make the growth effect more interesting.

<<You might want to set the first key on the growMe attribute to be at -1. This will ensure that you don't have one lone particle growing by itself at the start of the animation if you move the rest of the keys to a later frame.>>

Part Two: Automating the setup using MEL

Home