PDA

View Full Version : per particle goal weighting


jporter313
04-08-2008, 12:55 AM
So I have a grid of particles that I want to move from one goal object to another goal object. I have accomplished this by animating the goal weights between the two, however, all the particles move between the goals at the same speed.

I would like to vary it so some particles move over slower than others. I figured that I'd do this by adding per-particle goal weight, however, when I click this it doesn't seem to do anything.

Can someone explain to me if this is the right way to accomplish what I want? and if so, how do I make it work?

Thanks.

Aikiman
04-08-2008, 05:45 AM
If you create you GoalPP you can write a creation expression like...

goalPP=rand(0,0.3);

which assigns a different goal weight to each particle. Or if you want to do it manually select the particles in component mode and go to the Component Editor and change the values there. Make sure your goal weights per object level are 1 becuase this acts as a multiplier on your PP values.

jporter313
04-08-2008, 08:26 PM
First, thanks for the reply.

I tried this. Problem is these particles are not being emitted, they were created using the particle tool so I think the creation expression never runs. Also, this disables my ability to keyframe the goal weights. Any ideas for how to get around these issues?

jporter313
04-08-2008, 08:40 PM
Another issue I'm trying to solve is. I have a bevelled box instanced to the particles, but I want each instance of the box to pick up the color of a certain point in an image.

The desired effect is that I am taking an image and splitting it into it's pixels (each represented by an instanced box), and can have the pixels then fly around.

Aikiman
04-08-2008, 08:50 PM
In this case your birth frame is frame 1 so any creation expressions will work if your timeslider begins on that frame. The cool thing is you can have the random value change per particle when the goal weights per object change so you kinda get 2 creation expressions.

To still have access to keyframe the goal weights try using the channel box on the particle shape, or keyframe your weights before you add the per particle ones.

Aikiman
04-08-2008, 08:58 PM
Another issue I'm trying to solve is. I have a bevelled box instanced to the particles, but I want each instance of the box to pick up the color of a certain point in an image.

The desired effect is that I am taking an image and splitting it into it's pixels (each represented by an instanced box), and can have the pixels then fly around.

Yeah unfortunately Maya cant colorPP the instancer node yet which is a right bummer so you have to find work around for that one. A cheap and nasty is to throw the image file into a surface emitter and emit particles to inherit the color of the image that way but again you cant use the instancer. Or you could try baking the texture onto a whole lot of rigids but of course if there are hundreds of them Maya chokes.

jporter313
04-08-2008, 09:58 PM
man, that no color thing really throws a wrench in the gears. Hmm. What about sprites? can it color sprites?

Hmm, actually, I wonder if I could accomplish this by rendering one time with the sprites, then using the same simulation but doing colored particles instead, and then compositing them together.

Aikiman
04-08-2008, 10:20 PM
how many particles you talkin bout here?

jporter313
04-09-2008, 05:05 PM
21037. Basically it's an HD frame (1920x1080) downsampled to 192 x 108.

Aikiman
04-09-2008, 07:58 PM
Okay well I dont know what kind of effect you re after exactly but with particles the size of a pixel and with so many why dont you just use points and emit from a texture?

BFinlay
04-10-2008, 12:34 AM
What do you have planned for your objects? Maybe you don't need particles after all? If the beveled cubes are behaving in some sort of coordinated fashion you might be able to approach your effect in a different way.

jporter313
04-10-2008, 06:57 PM
The basic idea behind the movement is that I'm going to have the particles move from one plane to another (changing from one image to the other), in between I think I'm just going to play with forces a bit and try to come up with some interesting animation.

I also found a good example of a similar effect:

http://www.youtube.com/watch?v=s5QiqbHp5Q8

at the end of this commercial, where the blocks move to form the pixels of the Zune screen, that's sort of similar to what I'm trying to accomplish.

As I understand it, this is easy to do with C4D, but I don't really want to spend a few thousand dollars and invest the time learning another piece of software.

BFinlay
04-10-2008, 08:03 PM
Depending how much MEL you are willing to do, and how much flexibility you need, you can skip particles entirely for that. Just build a loop to instance your object and set it's position, then use colorAtPoint to sample an image at that corresponding relative position. Set the color of your geometry to match and move on to the next bit of geometry, until your entire array is built with one cube per pixel, or whatever.
To add the ripple animation, you can give each of your instances a runtime expression that monitors it's relative location on a ramp texture the whiter the ramp, the higher in Y.
The number of objects you're considering is pretty high, so consider how many you need to see at once.
Note that depending on your camera angle and output resolution, you may want to fake the resolution with fewer blocks, or you'll end up with severe moire interference patterns, whether you use MEL or particles to generate your instances.
Also remember this sort of thing is where efficiency starts to count. Anything that lags your loop even briefly, lags it x 20,736!

jporter313
04-10-2008, 08:26 PM
Thanks BFinlay. I think I might halve the resolution yet again to get it down to a more manageable number. As far as writing that expression, I really don't know where to start. I guess it's time to start reading that Maya Programming book that's been sitting on my desk. I don't see Closest point on surface in the index though.

BFinlay
04-10-2008, 08:42 PM
I use Maya to do simulations for a client with a special architectural cladding product that has similarities with your desired effect (obviously the cladding doesn't make the wall animate, but there are similarities).
The best way to figure out your minimum resolution is good ol' Photoshop. Take your HD image and resize it down until you find it is too blurry, blocky, etc., then take a few steps back. That'll give you a good idea how low you can go and still show up the picture. Often the coolest part of that sort of effect is that the final image is still a bit pixellated, reinforcing to the viewer that the pic is made up of all those blocks.

I think colorAtPoint is what you are after for sampling your image to find out what color to make your blocks. The way it works is, you take your block that is instanced, say at 0.5, 0.5 (the middle of your feild) and you look up what color the pixel is in your image at 0.5, 0.5. The image doesn't even have to show up in your render, doesn't have to be assigned to geometry. You're just saying, Hmm. This block is in the top left corner (for example), let's see what the top left corner pixel color is.
You CAN put the image on a surface as well, but the colorAtPoint samples the actual file node you point it at, not what is physically near the block.

jporter313
04-10-2008, 11:51 PM
Ok, so I'm trying to emit the color from a texture and have the particles form a grid.

Here's the issue:

When I use emit from surface, it emits the [article from a random point on the surface. I need them to be in a regular grid, so I thought I could do this by setting the emission plane as a goal object .

This forms the particles into a grid, but because they were emitted from random points on the surface initially the order they snap onto the vertices on the plane is totally arbitrary to where they were emitted from, and therefore, their color.

Does anyone know how to get around this? Ideally I'd like to emit a single particle from each vertice on the plane in order of vertice number. Is there any way to do this? Can anyone think of another way to get around this problem?

jporter313
04-11-2008, 08:19 PM
Anyone have any ideas for this?

BFinlay
04-11-2008, 09:16 PM
Assuming you selected your textured plane and did a Particles|Emit from Object, I suspect you need to change your Emitter Type to Directional. That way they emit from vertices, by default. Ensure you have assigned an RGB PP attribute to the particle and clicked Inherit Color on the Emitter node, you can then emit only the number of particles equal to the number of vertices, then stop, select the particle, set initial state, then delete the emitter (or if you have other plans for it, turn the Rate to zero). That should leave you with a particle object with 1 particle per vertex, colored how you like 'em.

jporter313
04-11-2008, 09:24 PM
Thanks again Bfinlay, I'll try that.

BFinlay
04-11-2008, 10:26 PM
Whoops! Nice idea, in theory. I forgot the inherit color only works with the Surface emitter type.
There is a way to sort this out though. Using a surface emitter and the inherit color technique, store each particle's U and V on creation (initU, initV) and then set it's goalU goalV equal to those. That way you are emitting from vertices and obtaining the particle color and then you are attaching the particle back to it's own birthplace. You can then use goal offset to manipulate/animate the particles.

jporter313
04-11-2008, 11:02 PM
Ok, so next problem. I did all that, but if I change the emitter type from surface to directional. It does emit from the vertices like it should, but it also disables all the texture emission attributes, so no color. Any way to get around this, or am I back at square one again?

jporter313
04-14-2008, 06:40 PM
Anyone have any thoughts? (or in other words, BUMP)

jporter313
04-23-2008, 05:34 PM
so I ended up writing a script to solve this problem. Here it is:

global proc particleGridCreate ( string $particleObjectName, string $particleColorTargetName, float $vertPos, float $horPos, float $gridSpacing, int $gridWidth, int $gridHeight) {

// particle creation variable definition

string $createCmd = ("particle -n " + $particleObjectName);
float $newLinePos = $horPos;
int $h;
int $w;

// particle color variable definition

string $colorCmd;
int $colorIndex = 0;
float $colorVertPos = 0;
float $colorHorPos = 0;
float $vertFloatConvert = $gridHeight;
float $horFloatConvert = $gridWidth;
float $colorVertSpacing = (1 / $vertFloatConvert);
float $colorHorSpacing = (1 / $horFloatConvert);
int $c;
int $cw;

// concatenate particle creation command string ($createCmd)

for ( $h=0; $h < $gridHeight; $h++) {

for ( $w=0; $w < $gridWidth; $w++ ) {

$createCmd += ( " -p 0 " + $vertPos + " " + $horPos );
$horPos += $gridSpacing;
};

$horPos = $newLinePos;
$vertPos += $gridSpacing;
};

// create the particle grid

eval $createCmd;

// add an rgbPP attribute to the particle object

addAttr -ln "rgbPP" -dt vectorArray ($particleObjectName + "Shape");
addAttr -ln "rgbPP0" -dt vectorArray ($particleObjectName + "Shape");

// assign colors to their associated particles

for ( $c=0; $c < $gridHeight; $c++) {

for ( $cw=0; $cw < $gridWidth; $cw++ ) {

float $colorArray[] = `colorAtPoint -o RGB -u $colorHorPos -v $colorVertPos $particleColorTargetName`;
particle -e -attribute rgbPP -id $colorIndex -vectorValue $colorArray[0] $colorArray[1] $colorArray[2] $particleObjectName;
$colorHorPos += $colorHorSpacing;
$colorIndex++;

};

$colorVertPos += $colorVertSpacing;
$colorHorPos = 0;

};

};

Here are explanations of the input variables:

$particleObjectName: what you want the output particle object to be named.

$particleColorTargetName: the name of an existing texture node in your scene from which the particles will inherit their color

$vertPos: the lower right grid corner Y position (I know this is odd, but this script was written quickly for a project, I'll work out the kinks later)

$horPos: the lower right grid corner Z position

$gridSpacing: the spacing in world units between each particle in the grid

$gridWidth: the number of particles wide you would the grid to be

$gridHeight: the number of particles high you would like the grid to be

if you want to check out the creation process, take a look at this thread:

http://forums.cgsociety.org/showthread.php?p=5106995#post5106995

Enjoy,

Justin

(Just a note, this script has gone through almost no testing, so if you find something wrong with it, let me know)

CGTalk Moderation
04-23-2008, 05:34 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.