Requirements

Prerequisite knowledge

Experience with other particle systems or experience with Away3D will help you make the most of this article.

 

Additional required other products

User level

Beginning

The Away3D 4.1 alpha release includes support for creating high performance, GPU-based particle systems with a powerful and configurable API.  You can use this ability to implement incredible effects in your 3D projects. This tutorial introduces the basics of the API, including the particle geometry class and the animation set initialization function for controlling a particle’s life and behavior.

Particle geometry

The first thing you need for particles is a set of geometries. Each element of this set will represent a type of particle. You can use any geometry in the set, including a built-in geometry primitive provided by Away3D or an external geometry loaded from a file. However, I geometries with many vertices are not recommended, as they will incur a heavy load and performance will suffer.

You may be wondering why the geometry set is predefined rather than created on the fly like some other particle systems. This is due to the limitations placed on vertex buffer uploading, which if you add the geometries of particles dynamically, needs to occur much more frequently. Uploading a vertex buffer carries a performance cost, so it’s a good idea to reduce such uploads if possible. In addition, a dynamic particle geometry has restrictions on sharing the vertex buffer across different animation instances.

The demonstration included with the sample files for this tutorial uses CubeGeometry as the geometry set element. You can find this sample code in TheBasicTutorial.as file:

var cube:Geometry = new CubeGeometry(10, 10, 10); var geometrySet:Vector.<Geometry> = new Vector.<Geometry>; for (var i:int = 0; i < 1000; i++){ geometrySet.push(cube); }

The code above adds 1000 cube geometries to a geometry set. If required, you can mix together different geometry types in the same geometry set.

Once the set is ready, you use the particle helper API to convert your set to the final particle geometry:

var particleGeometry:ParticleGeometry = ParticleGeometryHelper.generateGeometry(geometrySet);

You now have a final particle geometry instance, ready for animation.

Particle lifetime

The next step is to create a particle animation set. You may already be familiar with the concept of particle lifetime cycles. In a traditional particle system, a particle has its lifetime value, through which other properties (color, position, and so on) are controlled.

In Away3D, a particle has a startTime property related to the system time, and an optional duration property. (If no duration time is specified, the particle will have infinite duration). The delay property (also optional) represents the delay time between the end of a particle’s duration and the start of another duration. When these properties are put into use, a particle will appear at its start time, remain alive for its duration time, and then disappear for its delay time.

Because these properties are fundamental to the time calculations inside the GPU code, you have to predefine which of them will be used. The first parameter of the ParticleAnimationSet constructor indicates whether you will be using the particle’s duration property. The second indicates whether you will use a looping particle timeline (so that once the particle has completed its cycle, it automatically starts a new one). The third indicates whether the particles will disappear for the delay time before restarting their cycles.

In this example, all three properties are set to true:

var animationSet:ParticleAnimationSet = new ParticleAnimationSet(true, true, true);

It’s important to note that these are not properties of the animation set. If they were, all particles would have the same properties and would appear and disappear at the same time. Instead you use a function that sets each particle’s properties separately. Because they are local to each particle and set only once, startTime, duration, and delay are known as local static properties. The function that sets these properties will be invoked for every particle. You can identify the index of the particle using the ParticleProperties::index value, and then set the ParticleProperties::startTime, ParticleProperties::duration, and ParticleProperties::delay values for the particle; for example:

animationSet.initParticleFunc = initParticleParam; private function initParticleParam(prop:ParticleProperties):void { prop.startTime = prop.index * 0.005; prop.duration = 10; prop.delay = 5; }

The code above creates a set of local static properties that will cause the particles to start their cycles 5 milliseconds apart, remain alive for 10 seconds, then go to sleep for 5 seconds.

Particle position

Other particle systems have an emitter that you use to control the originating position of each particle. The Away3D particle system implements the same functionality more effectively through behaviors (one of the most important concepts in the particle API).

The ParticlePositionNode class can control the position for every particle in the ParticleGeometry instance. The nature of its control is determined via a mode property in the class constructor. This can take three different values:

  • ParticlePropertiesMode.LOCAL_STATIC (particles can have different starting properties for the behavior)
  • ParticlePropertiesMode.GLOBAL (all particles have the same starting properties)
  • ParticlePropertiesMode.LOCAL_DYNAMIC (particles can have different properties that are controlled on the fly)

The LOCAL_STATIC and GLOBAL modes can share GPU resources across animation instances resulting in high performance. So, it is a good idea to use these two modes as much as possible.

This example uses ParticlePropertiesMode.LOCAL_STATIC mode:

animationSet.addAnimation(new ParticlePositionNode(ParticlePropertiesMode.LOCAL_STATIC));

It controls the position value through the initParticleFunc function:

private function initParticleFunc(prop:ParticleProperties):void { prop.startTime = prop.index * 0.005; prop.duration = 10; prop.delay = 5; //calculate the original position of every particle. var percent:Number = prop.index / prop.total; var r:Number = percent * 1000; var x:Number = r*Math.cos(percent * Math.PI * 2 * 20); var z:Number = r*Math.sin(percent * Math.PI * 2 * 20); param[ParticlePositionNode.POSITION_VECTOR3D] = new Vector3D(x, 0, z); }

Before you can preview the effect, you have to create the material, mesh, and animator object for the particles. This takes the same approach as other forms of animation in Away3D.

//create material, mesh and animator var material:ColorMaterial = new ColorMaterial(0xff0000); var particleMesh:Mesh = new Mesh(particleGeometry, material); var animator:ParticleAnimator = new ParticleAnimator(animationSet); particleMesh.animator = animator; animator.start(); _view.scene.addChild(particleMesh);

Particle velocity

Next, you’re ready to make the particles move. For this, you will use another behavior, the ParticleVelocityNode, which is a particle animation node used to set the starting velocity of a particle.

You already know that you should be using either LOCAL_STATIC or GLOBAL for the mode as much as possible. But which is best for this application? Internally, the LOCAL_STATIC mode uses a stream of registers to pass the data to the GPU, so that the data can be represented per particle. However, GLOBAL mode uses constant registers to pass the data per behavior. The number of available stream registers is fewer than the number of constant registers, and stream registers require more data and more initialization time. So as a rule, you should opt for GLOBAL mode over LOCAL_STATIC when possible.

In this case, the goal is to have all particles move with the same velocity, so you can use the ParticlePropertiesMode.GLOBAL mode. The code looks like this:

animationSet.addAnimation(new ParticleVelocityNode(ParticlePropertiesMode.GLOBAL, new Vector3D(0, 50, 0)));

And here is the result:

Where to go from here

You have seen how to create a particle geometry, how to set start time and position properties on individual particles, and how to make them move. Of course, the API has many more features than those covered here, but you now have a good starting point from which you can build awesome effects! As just one example, you can create the following effect using the only the features described in this tutorial:

Here are some resources that you can use to continue learning about Away3D: