Using Maya Per Particle Attribute scripting to transfer colors from images is not as hard as it seems.  This technique allows a user to apply color patterns from an image library hidden from the rendering scene.  The PerParticle attribute for RBG color is the focus of this article.

First off, you’ll need a little background in MEL coding, the Dynamics WB, and hardware rendering.  There are dozens of tutorials on how to use these tools, and if you are looking for a quick start on MEL, feel free to read YSYT.

When you make a particle object in Maya (regardless if it’s in MEL or just manually generated), you have several perParticle attributes that allow you to modify each node individually.  If you just put a lambert on the entire particle assembly, it will be a uniform color.  So we must use MEL scripting to make more advance coloring capabilities.

For this example, toss a simple particle emitter with a standard Omni directionality.  Place an object as a target and keyframe it’s location to several places on the XY Plane.  Lastly, make a geometric plane on the XY Plane and make a material on it with a mapped image file.  Call this image file as “file1.”  Hide file1.

Activate the perParticle attribute for colorRGB and velocity.  Refer to the perParticle attribute section in the Maya documention if you don’t know how to do this.  perParticle attributes are strange, and they require the user to set up the runtime expression manually.

MEL Scripting screen capture of color perparticle attributing, Nick Pisca 2009

MEL Scripting screen capture of color perparticle attributing, Nick Pisca 2009

Create a runtime expression on the particle emitter and place this code in it.  This script is short and sweet.  It does two things:  keeps the location of the particles on the XY Plane, and also colors objects by the hidden “file1” object.

Code:
vector $CurPos = particleShape1.position;
particleShape1.velocity = <<1,1,0>>;
float $VMag;
float $VE[] = `pointPosition nurbsSphere1.cv[1][1]`;
vector $VecPos = <<$VE[0],$VE[1],0>>;
vector $VDiff = $VecPos - $CurPos;
$VMag = mag($VDiff);             //Distance
vector $VecUnit = unit($VDiff);  //Unit (1) vector
vector $SpeedVec = ($VMag/2)*$VecUnit;
if ($VMag < 7) {
particleShape1.velocity = $SpeedVec;
}

Code:
if (($CurPos.x)<10 && ($CurPos.x)>0) {
if (($CurPos.y)<10 && ($CurPos.y)>0) {
float $PtInSpace[] = {($CurPos.x),($CurPos.y)};

Code:
float $RGB3[] = `colorAtPoint -o RGB -u ($PtInSpace[0]/10) -v ($PtInSpace[1]/10)  file1`;
vector $RGBvec = <<$RGB3[0],$RGB3[1],$RGB3[2]>>;
//float $RR = rand(0.0,1.0);
particleShape1.rgbPP = $RGBvec; //<<$RR,0,0>>;
};
};

You may need to scaleXY the “file1” plane up or down according to your project scale.  Or you can modify the code to accommodate the project size as well.  I’m using a trick to get this to work:  everything stays in 2D.  A long time ago, I wrote a MEL script to do a real 3D-camera-orientation surface-point query of the RGB, but that was dramatically larger than this code.  I’ll see if I can dig up that project because it lead to some crazy results.  Here’s an image of an instance of the code:

Nick Pisca rocks.

Generative Scripting Capture by Nick Pisca.