By now, many of us are now familiar with a new gallery from Lee Griggs, a talented artist who created beautiful images using Maya and XGen combined with rendering in Arnold like the image below. He even offers a tutorial on the effect he created here.
Finding his images extremely inspiring, I found myself creating what I have been calling the “Lee Griggs” effect using my tools of choice: 3DS Max and particle flow and I thought I would share my discoveries in a short tutorial. Particle Skull provides a great, informative tutorial on this as well as other great particle tutorials (tutorial linked below). Since the effect is so popular, there are many other tutorials out there on this topic but the difference in my tutorial is the hexagon grid.
The effect is basically a grid of very small cubes that re-size vertically according to some type of data input. In this case, it is often a colored or a black and white map in which black means a value of zero and the cube is flat on the ground and white is a value of one and the cube is fully lifted. Using different image inputs and maps with texture and depth can create very interesting and beautiful results, as Lee Griggs demonstrates results in his gallery.
I found it was pretty straight forward to create this effect using particle flow and the pflow toolbox data operators, which are now bundled with 3DS Max and are referred to as Advanced Data Manipulation tools in the 3DS Max reference. My first version of this effect was created by spawning a grid of particles by positioning a particle on every vertex of a plane. Then, each particle samples the geometry surface that it is closest to – which means it will sample the point on each vertex of the plane they were spawned from. The plane has a black and white map on it so the sample already returns a value of 0 to 1 so it was just a matter of piping that value into the scale of each cube. The first challenge of the effect is that I wanted it to be procedural in resolution – meaning that I could simply apply a turbosmooth to the plane and the cubes would automatically re-size themselves so they would always fit in a perfect grid. This is so I could tweak the animation and movement of the effect and the map at low resolutions and increase it easily when the effect was ready to render. This was achieved by sampling the number of faces on the plane and taking the square root of that number, which returns the segments in one side of the plane. That was then divided by the length of the plane, which returns the length of a single polygon of the cube grid. That value was used to control the scale of the cubes since it dynamically changes every time the face count changes on the plane. You can also achieve this by simply dividing the length of the plane by the length segments but there is currently a limit of 1000 x 1000 segments in 3DS Max and I wasn’t sure how dense I wanted the particle field to be at that point, so I used the “Object number of faces” operator instead. Later in this tutorial I will show exactly how to calculate it using data operators. Here is a quick viewport snapshot of the cube grid with a map controlling the height of the cubes:
The final challenge of the effect involves some more math. I decided early on that I wanted to use hexagon shapes in a grid formation instead of cubes. Hexagons do not fit together like a cube does (side by side), they’re offset every other row. I did some quick research on the anatomy of a hexagon since I had apparently lost my knowledge of hexagonal geometry from 10th grade. I found this website that details how the hexagons relate to triangles and how their sizes are calculated and used that information to build my system. The plane they’re spawned from should not be square anymore because hexagons are not square and they don’t fit together so simply. The size of the plane they’re generated from must reflect the relationship of the hexagon’s length to height ratio to prevent extra space between them. A hexagon with a radius of 1 means that the length each segment is also 1. Its diameter is 2 and its height is the square root of 3 (which is approximately 1.73). With that ratio of 2 x 1.73 in mind, I made my spawn plane 200 x 173 units, which gives each vert the correct spacing horizontally. The plane also had 9×9 segments so we would create a vertex grid (and also particle grid) of 10×10. It was then a matter of spawning a hexagon on each vertex of the plane, and then spawning child particles from those initial particle positions and then adding the position offsets to them as demonstrated in this step by step image:
The first set of spawn (called “Spawn 1” in the above example) simply moves vertically the same distance as the height of the particle (which is not just √3 anymore because we must take into account the size of the grid we’re using). Since our grid is 200 x 173 with 9×9 segments, each poly is 22.2222 units vertically. Since our parent particle moves from one vert position to halfway between two verts, we will use half of that value for the vertical offset so our “spawn 1” should move vertically 11.1111 units.
The position offsets for the second group of hexagons (“spawn 2”) can be seen in the next image, which introduces the anatomy and spacing of the hexagon and the hexagonal grid. We see that since the height of the hexagon is the square root of 3, we simply use half that value to shift the spawn particle vertically and since we just learned that each hexagon’s height is 11.1111 in a grid this size, then it moves down 5.5555. We also know that the the horizontal distance it needs to move is 1.5 times the distance of the radius. We just need to calculate our hexagon’s radius for this grid size.
To make the hexagon to fit properly in our grid size of 200 x 173 with 9×9 segments, the value of the hexagon radius needs to be exact. Since we know our grid length is 200 with 9 segments, then we know that the length of each poly of the plane is approximately 22.22 and two hexagons fit vertically per poly so the height is 11.1111 as we learned earlier. If we know the height, we can use the hexagonal ratio I mentioned before to calculate the radius as demonstrated in the following image. We can see the hexagonal ratio on the left hexagon and our new height of 11.11 in the hexagon on the right. We now just set up an equation to and solve for the radius (“r”). In the equation below, the 2s cancel each other out and you find that r = 11.11/√3 which equals 6.415 (if you use exact values without rounding to the hundredth place). So our radius must be 6.415.
To make the effect procedurally re-size the hexagon radius based on the size of the faces, I used the same calculation I used before, which involves taking the square root of the number of faces on the plane and dividing it by the length and as long as the radius value initially equals 6.415, then it will automatically re-size properly based on the changing polygon length as you add segments (this works with additional modifiers like turbosmooth since it measures the number of faces instead of the segments). You can see that section of my data operator in the following image.
Here are some quick viewport snapshots of the effect in action: