Here I will present some useful tips for VFX artists who use particles in their work. It will be mostly Maya but increasingly Houdini as I learn the ropes. Please feel free to comment or correct as appropriate. Please take a look at my other blog specifically focussing on Crowd FX: www.crowd-effects.com

## Tuesday, 29 November 2011

### Motion Vectors for hardware particles

I have not got very far before I came across some vector maths...

Here is the setup which works for a camera pointing exactly down the z-axis.

Here is the render loaded into Nuke. Notice the RGB values.

I now need to find a way to convert World Velocity to Screen Space Velocity.

In a MEL expression. Hmmm, time to ask the Forum

After some great advice from Zoharl, I grabbed some code which uses the camera's worldInverseMatrix to transform the velocity vector.

Here is the expression:

//multiplier

float $mult=0.5;

//get the particle's World Space velocity

vector $vel=particleShape1.worldVelocity;

float $xVel=$vel.x;

float $yVel=$vel.y;

float $zVel=$vel.z;

// create particle's velocity matrix which is in World Space

matrix $WSvel[1][4]=<<$xVel,$yVel,$zVel,1>>;

// get the camera's World Inverse Matrix

float $v[]=`getAttr camera1.worldInverseMatrix`;

matrix $camWIM[4][4]=<< $v[ 0], $v[ 1], $v[ 2], $v[ 3]; $v[ 4], $v[ 5], $v[ 6], $v[ 7]; $v[ 8], $v[ 9], $v[10], $v[11]; $v[12], $v[13], $v[14], $v[15] >>;

//multiply particle's velocity matrix by the camera's World Inverse Matrix to get the velocity in Screen Space

matrix $SSvel[1][4]=$WSvel * $camWIM;

vector $result = <<$SSvel[0][0],$SSvel[0][1],$SSvel[0][2]>>;

float $xResult = $mult * $result.x;

float $yResult = $mult * $result.y;

float $zResult = $mult * $result.z;

//rgbPP

particleShape1.rgbPP=<<$xResult,$yResult,0>>;

So far it seems to be working, but I will try to test it and see if it breaks down.

Thanks to Zoharl on the CGTalk forum and to xyz2.net and 185vfx who came up with the original matrix manipulation code.

## Thursday, 10 November 2011

### Emit particles upon the death of another particle

vector $pos = death_particleShape.position;

vector $vel = death_particleShape.velocity;

float $randVelMag=10;

float $randPosMag=1;

float $velMult=0.1;

float $emitNum = rand(1,3);

for ($i=0; $i<$emitNum; $i++) {

vector $randVel = <<$randVelMag*rand(-1,1),$randVelMag*rand(-1,1),$randVelMag*rand(-1,1)>>;

vector $randPos = <<$randPosMag*rand(-1,1),$randPosMag*rand(-1,1),$randPosMag*rand(-1,1)>>;

vector $newVel=<<($velMult*(($randVel.x)+($vel.x))),($velMult*(($randVel.y)+($vel.y))),($velMult*(($randVel.z)+($vel.z)))>>;

emit -o birth -position (($randPos.x)+($pos.x)) (($randPos.y)+($pos.y)) (($randPos.z)+($pos.z)) -at velocity -vv ($newVel.x) ($newVel.y) ($newVel.z);

};

};

basically it is an EMIT command with some randomness added to the position and velocity parameters.

$randVelMag is a multiplier for the randomness in the velocity of the birth_particle when it is emitted

$randPosMag is a multiplier for the emitted position of the birth_particle

I then applied some turbulence fields to the birth_particles to get them to wiggle a bit and tweaked the conserve on them and the trail_particles. Here is a rendered frame.