There
are situations where a phenomenon's velocity
or speed is related to it's behavior or appearance.
Perhaps the incandecence increases as a particle
moves faster... or the color changes from blue
to red. Perhaps some dust is resting on an object,
but once it gets blown away it also begins to
dissipate and fade. These effects can be achieved
by understanding how to reference particle speed,
which is not a default particle attribute.
Attributes
related to speed which particles do have by
default are velocity and acceleration. It is
important to understand these for they can cause
confusion for those new to this terminology.
Everyone knows what speed is... we are reminded
to be aware of it whenever we get in a car.
Speed is a 'float' number which tells us how
fast we are moving. Velocity and acceleration,
however, are 'vectors', which not only tell
us magnitude but also direction. A velocity
of <<0,10,0>> tells us that a particle
is moving in the positive Y direction with a
speed of 10 units per second. An acceleration
of <<0,10,0>> tells us that a particle
is speeding up in the positive Y direction.
Thus when trying to determine a particle's speed,
our focus is on the velocity, not the acceleration.
With
this in mind, there are a couple ways we could
query a particle's speed: custom variables or
custom attributes. For
example, assuming we have a particle object,
particleShape1, which has the rgbPP attribute,
we could write the following runtime expression:
float
$speed = mag(particleShape1.velocity);
if ($speed > 5)
particleShape1.rgbPP = sphrand(1);
else
particleShape1.rgbPP = rand(<<.2,.4,.6>>,<<.2,.5,1>>);
The
above expression will give us bluish particles
unless they start moving faster than 5 units/second
at which point they would become rainbow colored.
We defined a new variable called $speed which
was assigned the magnitude of the velocity vector.
The mag() function returns the magnitude of
any vector by taking the square root of x2+y2+z2.
So the magnitude of velocity is speed, which
is useful when the directionality is not needed.
An example where directionality is used would
be:
vector
$velo = particleShape1.velocity;
if ($velo.y > 5)
particleShape1.acceleration += <<5,0,0>>;
else
particleShape1.acceleration += 0;
The
above will cause particles to speed up in X
if their speed in Y is greater than 5.
So
custom variables have their place, as do expressions,
but what if you want to color particles based
on speed by using a color ramp. This is a case
where we will need to define speed as a custom
attribute.
With
general knowledge of the particle engine in
Maya, one should be aware that there are many
attributes which a particle shape node can have,
but does not by default: radiusPP, goalU, spriteNumPP,
etc. These attributes serve specific purposes
when added, yet we are also able to add 'custom'
attributes to particle objects which do not
serve any purpose when created. Their functionality
is determined by the user by assigning them
values to store, which other attributes may
reference.
So
we want to create an attribute called 'speed'.
With the particleShape node selected and the
attribute editor open, in the Add Dynamic Attributes
folder, click the general button. This opens
the Add Attribute window which has three tabs.
Select the left tab. In the name field enter
'speed', for attribute type choose 'float',
Per Particle Array. With the attribute created,
you will now see it listed in the Per Particle
Array Attributes folder of the particleShape
node.
We
chose PP Array because we want each particle
to have its own speed attribute... as any particle's
speed will likely be different from any other.
Now that each particle has 'speed', we need
to assign it a value. We want to write a runtime
expression as this is an attribute whose value
changes over time:
particleShape1.speed
= mag(particleShape1.velocity);
At
this point any other attribute of the particleShape
node can query this 'speed' attribute value.
For example:
particleShape1.opacityPP
= particleShape1.speed;
would
have the effect of getting particles to fade
out when they stop moving. Although this relationship
works well, it is not very complex. If you need
particles to fade on when they begin moving
but fade out when they reach a certain speed,
a ramp may be the most efficient technique to
design the relationship between opacity and
speed. Likewise, if we want color to change
based on speed, ramps are going to be our friend.
Something
you should know is that ramps are commonly connected
to attributes such as rgbPP, opacityPP and radiusPP
based on a particle's lifespan. This means that
a particle's 'Age' determines where in the ramp
the particle's attribute gets its value from.
Well, what we want to do is not base the query
on 'Age' but on 'Speed'.
With
'rgbPP' and 'speed' already added to the particle
object, right click on rgbPP in the Per Particle
folder and go to the creation dialog window
for Create Ramp. By default Input U is mapped
'none', and Input V is mapped to 'Age'. Change
Input V to 'Speed'. As you can see, any per
particle attributes which you have added will
appear in this list.
At
this point we have accomplished our goal to
relate speed to a color ramp, but there are
still a couple things left to do to get the
right results. The obvious first thing to do
is to edit the ramp with the required colors;
perhaps blue at the bottom and red at the top.
If you playback your scene, the particles will
no doubt be using a color from the ramp, but
the relationship of speed to the ramp will not
necessarily be evident. This is because the
ramp V positions go from 0 at the bottom to
1 at the top... but our particle speed attribute
does not necessarily go from 0 to 1. But this
is not to say that it can't. We simply need
to edit the runtime expression for 'speed':
particleShape1.speed
= mag(particleShape1.velocity)/$topspeed;
where
$topspeed is a guesstimate of the top speed
that any particle in the particle object will
hit. It is not necessary to be completely accurate,
as it makes little difference if only 50% of
the color ramp is being used. Once $topspeed
has been deduced, the effect should be clear,
assuming that the particle's speed -is- changing.
At
this point there is an optional step which can
be taking to increase the variety within the
particle color (or whatever attribute you are
relating to speed). Based on our current ramp
set-up, all particles travelling the same speed
will be the same color. This is because all
particles are using the left most edge of our
ramp (U = 0). What can be done is to add some
variation to the ramp, using any technique available
with Maya Textures (noise, color gain, etc),
then have each particle use a different U coordinate
along the ramp.
Add
a new attribute to the particleShape node called
'rand_u'. Then write the following creation
expression to assign a random number to this
new attribute:
particleShape1.rand_u
= rand(0,1);
Where
we previously had assigned 'Input U' to 'none'
when we created the ramp, we now want 'Input
U' to be mapped to the 'rand_u' attribute, while
'Input V' is still mapped to 'speed'. To change
the mappings after a ramp has already been created,
it is easiest disconnect/reconnect the ramp
by right clicking on the attribute in the Per
Particle Array Attributes folder.