Weíve been having a lot of fun here at flashandmath with surfaces made of particles. So we present the Stanford Bunny and other new beautiful surfaces with modification of earlier effects, a significant optimization of the code, and a simple z-sorting method. The optimized code allows for revolving in 3D over 200,000 particles. Click each screen shot or the corresponding text link to open a Flash movie. Download source code from the link below.
The Stanford Bunny:
"Torsion" - 200,100 particles:
"Ribbon" - 160,000 particles:
"Piercing" - 120,000 particles:
- Download all source files corresponding to these effects: bunny.zip
Depth based lighting and z-sorting
In our previous particle surface examples, 100,000 Glowing 3D Particles Run Smoothly in Flash Player 10.1 and Particles Made of Light, surfaces were created with an additive lighting effect that made the particles appear to be made of light. For a different effect, we have removed this additive effect to create opaque particles. The particles darken as they move further from the viewer.
Typically, when rendering a 3D scene, objects must be z-sorted. That is, we must know whether an object is in front of another, so that when we draw the object we donít cover up something that should be shown in front of it. For the particle effect here, this type of z-sorting can be done in a very simple way because particles darken as they move further back. Before drawing a new particle in a pixel position, we simply look at the current color in that position, and see whether it is darker than the particle we are about to draw. If the pixel in that position is already brighter than the one we are about to draw, then there must be a particle in that position already that is closer to the viewer, so we donít draw the new particle because it should be hidden.
Optimizing the Code
The particle animations we have presented in our earlier posts were already fairly optimized for performance; for example we used a linked list to store our particles rather than the slower method of using an array (see Pixel Particles Made Simple - AS3 Flash Tutorial for more information on linked lists and basics of particle animation). However, we have found another optimization technique which has greatly increased performance: reducing the number of variables. It seems that changing the value of a variable takes a significant amount of time when it happens repeatedly within a loop. Thus, finding ways to reduce the number of variables can increase performance. In the examples presented here, we use a streamlined SimpleParticle3D class instead of our earlier Partcicle3D class. We removed all methods and properties of the class except for those needed in our examples.
If you examine the code which computes the 2D pixel position of the particles as they are rotated in space, you will see that we have compacted the code to as few lines as possible, using a small number of variables. The code in our earlier examples is easier to understand, because in clear and separate steps we compute rotated 3D coordinates from fixed 3D coordinates, and projected 2D coordinates from these rotated coordinates. That approach made the code more readable, but required several variables to be stored and retrieved. It is probably good practice, therefore, to first write code which is easy to understand, using separate calculations for individual quantities. But once the code is complete and working properly, one can look for ways to combine these smaller calculations into more compact lines of code with fewer variables.
The Stanford Bunny
The first example shown above uses a famous 3D model known as the Stanford Bunny, which was computed by scanning an actual clay model of a bunny. The data is available here, and an interesting history of the model can be read here.
Since the data was supplied as a PLY file which contains information not only about vertex positions but also polygons and other information, we had to do a little work to extract the coordinates of the particles from the data. First we created a new text file which contained only the vertex data for the bunny. This data is presented simply as a long list of numbers, where each vertex has five numbers associated with it: x, y, and z coordinates, plus two more variables for "confidence" and "intensity." To extract the data for the particles, we load the text file at runtime, and parse the data by splitting it up into individual numbers stored in an array. To split the long text into individual pieces, we use the String.split() method, where the splitting occurs every time whitespace (space, tab, or newline characters) appears. Note that we have used a Regular Expression to denote whitespace. More information on Regular expressions and operations with Strings can be found in the ActionScript 3.0 Bible, by Bernstein, Wright and Noble.
Related Flash and Math Effects and Tutorials