ParticleScript Basics
This chapter is about the ParticleScript language.
The first step in a ParticleScript program is to declare particle attributes. Here is a typical set of attribute-declarations:
varying float3 position varying float3 velocity varying float4 color
This means that every particle has a position and velocity, both of which are float3. The keyword 'varying' means that different particles might have different positions - in other words, it means that the particles don't all have the same position.
The words 'position' and 'velocity' are just attribute names, not keywords. The system does not assign any particular meaning to these words. There is no built-in physics calculation in ParticleScript.
The opposite of 'varying' is 'uniform'. For example:
varying float3 position varying float3 velocity uniform float3 gravity
This means that all particles individually have position and velocity. There is also a gravity force which all particles share - ie, the gravity force is the same for all particles. Uniform attributes can be given initial values:
varying float3 position varying float3 velocity uniform float3 gravity = [0, 0, -9.8]
Attributes can be of type float1, float2, float3, or float4. There are no other attribute types. Constants in ParticleScript can also be float1, float2, float3, or float4. Constants are written as: an open bracket, a series of floating-point literals separated by commas, and a close-bracket. Constants of type float1 can omit the brackets.
Assignment Statements
After the attribute declarations come the executable statements. The most common of the executable statements is the assignment statement:
position = position + velocity * 0.01
At any given time, a subset of the particles are selected. Assignment statements implicitly apply to every selected particle. If there are no commands to select particles, then by default, every particle is selected. So if the statement above were the only executable statement in the particle system, it would implicitly be done to every particle.
Assignment statements cannot assign to uniform attributes. Uniforms can only be set at initialization time, or in the Lua code.
Selection Sets
It is possible to write an assignment statement that operates on a subset of the particles using the select operator. Here is an example:
select (position.z < 0) color = [0,0,1,1]
The first command will select all particles whose Z-coordinate is less than zero. The second statement will set the color attribute (which must be declared float4) to blue. The second statement, an assignment statement, will implicitly affect only the currently-selected particles.
The select command above contains a boolean expression: (position.z < 0). Boolean expressions return "selection sets." The select command requires that the right-hand side be an expression that returns a selection set.
It is possible to store a selection set for later use. The following code does the same thing as the previous code:
selection lowparticles lowparticles = (position.z < 0) select lowparticles color = [0,0,1,1]
Now you have given a name, lowparticles, to the set of particles whose Z-coordinate is less than zero. You can select this group of particles again using "select lowparticles."
There is a built-in named selection set "all". If you say "select all," you will select all particles.
Spawning New Particles
To create new particles, you need to use one of the spawning operators. A common operator is spawnsteady, which spawns particles at a steady, fixed rate, specified in particles per second. The particles that are created have zeros in all their varying attributes. They must be initialized.
All spawning operators implicitly create a named selection set called "new", which contains a list of all the particles that were just spawned. This selection set makes it possible to initialize the new particles.
Here is some sample code that creates new particles and initializes them:
spawnsteady 5.0 select new position = [0,0,0] velocity = rand.unitvec
The first statement causes particles to be spawned, at a rate of 5.0 particles per second. It also implicitly sets the selection set 'new' to the new particles. The second statement selects the new particles. The two assignment statements only affect the new particles - they initialize the position to zero, and the velocity to a random unit vector.
Deleting Particles
The delete command requires you to pass in a selection set. It removes the selected particles from the system:
delete (position.z < 0)
In the example above, the boolean expression returns a selection set containing all particles whose Z-coordinate is less than zero. The delete command deletes them. This is a common command: it gets rid of particles that have fallen through the floor.
After a delete operator, all named selection sets are zeroed out (excepting 'all', which still references all particles).
Rendering Particles
To render particles, use one of the rendering commands. A typical example is renderorbs, which renders blurry round balls at specified locations:
select all renderorbs pos:position color:[1,0,0,1] size:0.1
Rendering commands cannot render a subset of the particles. For clarity, you must 'select all' before rendering.
Rendering commands usually use keyword-style parameters, explained below.
Keyword-Style Parameters
Some commands, especially the rendering commands, take lots of parameters. To make these commands easier to understand, the parameters are passed "keyword-style". Each parameter consists of a keyword, a colon, and an expression. In addition, some commands follow the keyword-parameters with keyword-flags: single words that alter the behavior of the command. The "renderorbs" command is a good example:
varying float3 position varying float4 color ... renderorbs pos:position renderorbs pos:position color:color renderorbs color:color pos:position renderorbs pos:position add
The renderorbs command takes three keyword-parameters: "pos," "color," and "size." It also accepts the keyword-flag "add". As you can see, the keyword-parameters can be specified in any order. The flags can also be specified in any order, though they must follow the keyword-parameters.
Automatic Type Conversions
Some expressions expect a value of a given type. If you pass in an expression of a different type, automatic conversion will take place.
When converting to a smaller type, the conversion involves truncation: the extra values are discarded. For example, converting [1,2,3,4] to float2 yields [1,2].
When converting a float1 to a larger type, the conversion involves replication. For example, converting [7] to float4 yields [7,7,7,7].
When converting anything other than float1 to a larger type, the conversion involves padding with zero. For example, converting [5,6] to float4 yields [5,6,0,0]. However, float1 is an exception.
Swizzling
The four elements of a float4 are called X,Y,Z,W in that order. It is possible to rearrange the values using a "swizzling operator." The swizzling operator consists of a dot followed by the letters X,Y,Z,W - not necessarily in that order. The swizzling operator extracts the named portions, in the named order, and constructs a new value from those:
# extracts three copies of Z from the constant - therefore, sets position to 3,3,3 position = [1,2,3,4].zzz # extracts W,Y,Z from the constant - therefore, sets position to 4,3,2 position = [1,2,3,4].wyz
Swizzling can be combined with automatic conversion. For example, let's say I do this:
varying float4 attr1 attr1 = [1,2,3,4].z
In this example, the swizzle operator takes the input [1,2,3,4] and returns the value [3]. Then, this value [3] is automatically converted to float4 to assign it to attr1. The automatic conversion produces [3,3,3,3].
Groups
Particle systems can contain multiple 'groups' of particles. Groups are almost completely disjoint - it is almost as if you had two separate particle systems. Particles in different groups have different attributes, different commands, and different selection sets.
To create a group, use the group name command. All commands that follow the group-declaration implicitly apply to particles in that group only.
Currently, groups are truly disjoint: there are not currently any commands that communicate between two groups. However, there will eventually be commands that pass data from one group to another.
- Printer-friendly version
- Login or register to post comments
-



