View Full Version : Applying colorAtPoint samples to individual particles in a single Particle Shape

04 April 2008, 10:00 AM
Hi There,

I'm attempting to find as many ways as I can to recreate a pin matrix animation similar to the Only video by Nine Inch Nails. I have one method which pulls colorAtPoint data samples from a texture at set divisions and applies it to objects placed in similar positions in 3D space, using one of the RGB values. eg:

inside 2 loops for $u and $v, where $mxU = max objects in U and $mxV = max objects in V

float $offset[] = `colorAtPoint -o RGBA -u ($u/$mxU) -v ($v/$mxV) textureFile`;
$objnum = ($objnum + 1);
$name = ($obj + $objnum + ".translateY");
float $mult = ($pos[1] * 50);
setAttr $name $mult;

and so on...

this works great, but is a little bit slow.

Is there a way to apply the same data to a individual particle positions in a particle grid rather than a polygonal instance?

If anybody knows, I would really appreciate the help.


04 April 2008, 04:21 PM
One thing that may help you: colorAtPoint can pull in a grid of samples, not just a single one. If you create an expression where you do one call to colorAtPoint(into a single array), then loop over your objects to set them from this array, it should be more efficient. (the indexing is described in the command doc for colorAtPoint)


04 April 2008, 08:46 PM
Thanks Duncan,

There was a reason why I didn't use this, the point being that I only need to get one variable from the each colorAtPoint - my texture is monochromatic - and I didn't want to wade through a huge pile of RGB values, having to extrapolate every third value, instead relying on pulling the first value from a smaller array. Was I wrong to do it this way?

Also when you say:

then loop over your objects to set them from this array, it should be more efficient.

What exactly do you mean by "loop over"? As I have a grid of 64 by 48 pins, landscape, I have their x and y positions set, their z position being offset by the colorAtPoint data in two loops, one for the U values and one for the V values of the animating texture file, I didn't think I needed any other values from the colorAtPoint results. I know you're a very busy guy, but could be a little more specific?

Also, seeing as you have answered with a method to streamline my current pipeline, is it, therefore, the only pipeline for this sort of thing?

04 April 2008, 12:48 AM
You could do something like:

float $offsets[] = `colorAtPoint -o A -su 64 -sv 48 textureFile`;
int $i;
for( $i = 0; $i < size( $offsets ); $i++ ){
string $name = ($obj + $i + ".translateY");
float $mult = $offsets[$i] * 50;
setAttr $name $mult;

This assumes that your pin objects are numbered in a raster ordering
number = (row + column*(numRows))

The -su,sv of the colorAtPoint command specify to sample a grid of points of those dimensions from the texture. The uv range is 0-1 in this case but you can specify the min/max uv for your sample grid (if you just wish to sample a portion of the texture).

The "-o A" flag specifies to return only the alpha values, although you may wish to set "alpha is luminance" on the texture if your file texture does not have an alpha channel.

I'm not sure if this will be faster for you, but it could be.


04 April 2008, 09:27 PM
I don't think this is exactly what you're looking for, but I just developed a script to create a grid of particles and then set their rgbPP based on samples from an image. You're welcome to cannibalize parts of it as needed. Here's the CGtalk thread:

The final script is at the end of the second page.



CGTalk Moderation
04 April 2008, 09:27 PM
This thread has been automatically closed as it remained inactive for 12 months. If you wish to continue the discussion, please create a new thread in the appropriate forum.