Here's a quick and easy way to create a procedural simulation of cell mitosis that, in my opinion, looks pretty impressive.
The simulation is based on a point cloud which is wrangled inside a solver. My main network looks like:
- The initial point cloud is crated with a Point Generate. The video above starts with just ten points.
- The positions of the points are randomized with a Point Jitter.
- The Solver contains my mitosis simulation VEX which is described below.
- The final render uses metaballs with a mode of Threshold Radius. This mode helps reduce the "popping" effect caused by the creation of new points.
- ...which are copied to each point with a Copy node.
The real action takes place in an Attribute Wrangle inside the Solver. It begins with a few lines that separate each point by moving it away from the average position of its neighbors:
int pointCloud = pcopen(0, "P", @P, 1 , 50);Each point is assigned an age attribute which is incremented by a small, random amount with each frame. If age is greater than one, I add a new point to the point cloud. The new point is slightly offset from the original point and the original point's age is reset to zero:
vector localCentre = pcfilter(pointCloud, "P");
vector v = set(@P.x - localCentre.x,
@P.y - localCentre.y,
@P.z - localCentre.z);
@P += v * 0.75;
if (@age > 1) {In previous projects, I've explicitly added attributes with an Attribute Create, however, it seems simply declaring age in the VEX adds it for me.
vector randOffset;
randOffset.x = -0.01 + (noise(localCentre.x + $FF * @age) * 0.02);
randOffset.y = -0.01 + (noise(localCentre.y + $FF * @age) * 0.02);
randOffset.z = -0.01 + (noise(localCentre.z + $FF * @age) * 0.02);
int newPoint = addpoint(geoself(), @P + randOffset);
@age = 0;
}
else {
@age += abs((random($FF * @ptnum)) * 0.05);
}
In the video above, I used the stock "red velvet" material with some added noise for displacement and, of course, added depth-of-field for the final render.
The default metaball mode, Field Radius, causes an apparent increase in radius when a new point is added to the cloud - as demonstrated in the video below:
Addendum
Here's an evolved example. In the VEX code, I've also added some code to add and increment a scale attribute:
if (@scale < 1) {The scale, which starts at zero, is inherited by the metaballs which prevents the "pop" effect when a new point is added.
@scale += 0.075;
}
The solver output is now plugged into two metaball nodes, but one of those metaball nodes acts as the input to a remesh and then onto a wireframe node:
This gives the effect of a collection of individual "cells" surrounded by a fine mesh - see above.
Nice! You know, you can add vectors by just adding them, you don't have to separate out the components! When it comes to creating attributes in VEX with the @ syntax, it's a good idea to specify the type as well: f@age in this case (f means float, you can have i or v for int or vector too).
ReplyDeleteThanks Patrick!
Deletecool stuff! there was an odforce thread where me and a few others exchanged ideas on simulating mitosis, I think yours looks the best, and is nice and clean. the only thing missing maybe is the ability to layer forces on top, but I don't think there'd be any reason you couldn't run this in a geo wrangle within a pop sim.
ReplyDeletethat thread if you're interested: http://forums.odforce.net/topic/26192-cell-expension-algorithm-suggestion/
Thanks Matt!
ReplyDelete