Linden Scripting Language Tutorial: Particle System

By Xah Lee. Date: . Last updated: .
Get your Xah Particle Maker today!

“Particle system” is used to simulate {smoke, fire, rain, fireworks, jet exhaust, explosion, blood, bling, …}. A particle in Second Life is created by the function llParticleSystem.

A particle is simply floating images (textures). LSL creates particles by the function llParticleSystem(). The parameters control how many particle images to float, the rate they are created, their duration, their color, in what direction they move, their speed, in what orientation, what size.

Remember, particles are simply a bunch of floating images and nothing more. By changing {the image, their number, direction of floating, size, color, orientation}, over time, they appear as {smoke, laser, rain, cloud, blood, explosion, …}.

The image used for particle is sometimes called a “sprite”. It essentially means a image moving around on the screen.

llParticleSystem() takes single list as argument. This list has the form [p1,v1, p2,v2, p3,v3, …]. The p are the parameter names and v their values. Not all parameters must be supplied, but they must be supplied in p v pairs.

omnious cloud
ominous cloud made of particles. It is made of hundreds copies of the same image (called the “texture” image), each with different size/scale, degree of coloring, degree of transparency, and positions on the screen. 〔➤see Second Life: Xah Particle Maker

Here's a simple example:

// a script that simulates a single firework burst, every 5 seconds.

 default
 {
     state_entry()
     {
         llParticleSystem([
                           PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_EXPLODE,

                           PSYS_SRC_MAX_AGE, 0.,
                           PSYS_PART_MAX_AGE, 9.,

                           PSYS_SRC_BURST_RATE, 5.,
                           PSYS_SRC_BURST_PART_COUNT, 500,

                           PSYS_SRC_BURST_RADIUS, .1,
                           PSYS_SRC_BURST_SPEED_MIN, 3.,
                           PSYS_SRC_BURST_SPEED_MAX, 3.,
                           PSYS_SRC_ACCEL, <0.0,0.0,-0.8>,

                           PSYS_PART_START_COLOR, <246,38,9>/255.,
                           PSYS_PART_END_COLOR, <246,38,9>/255,

                           PSYS_PART_START_ALPHA, 0.9,
                           PSYS_PART_END_ALPHA, 0.0,

                           PSYS_PART_START_SCALE, <.3,.3,0>,
                           PSYS_PART_END_SCALE, <.1,.1,0>,

                           PSYS_PART_FLAGS
                           , 0
                           | PSYS_PART_EMISSIVE_MASK
                           | PSYS_PART_INTERP_COLOR_MASK
                           | PSYS_PART_INTERP_SCALE_MASK
                           | PSYS_PART_FOLLOW_VELOCITY_MASK
                           | PSYS_PART_WIND_MASK
                           ]);
     }
 }

There are 2 types of parameters:

presets 015
Different particle effects. 〔➤see Second Life: Xah Particle Maker

The following are specific examples. Try them inworld.

Blinking Beacon

// This script is from http://xahlee.org/sl/ .
// Copyright © 2007 Xah Lee.
// Permission is granted for use or modification provided this note is intact.

// A blinking red beacon, using particle system

partyOn(){
 llParticleSystem([

 PSYS_PART_FLAGS
 , 0
 | PSYS_PART_EMISSIVE_MASK
 | PSYS_PART_INTERP_COLOR_MASK
 | PSYS_PART_INTERP_SCALE_MASK
 | PSYS_PART_FOLLOW_SRC_MASK
 ,

 PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP,

 PSYS_SRC_MAX_AGE, 0.,
 PSYS_SRC_BURST_RATE, 2.,
 PSYS_SRC_BURST_PART_COUNT, 3,

 PSYS_SRC_ACCEL, <0.0,0.0,-0.01>,

 PSYS_PART_MAX_AGE, 3.,
 PSYS_PART_START_COLOR, <1,0,0>,
 PSYS_PART_END_COLOR, <1,1,1>,
 PSYS_PART_START_ALPHA, 0.8,
 PSYS_PART_END_ALPHA, 0.,

 PSYS_PART_START_SCALE, <1,1,0>,
 PSYS_PART_END_SCALE, <.01,.01,0>
 ]);
}

default { state_entry() {partyOn();}}

Firework Explosion

// This script is from http://xahlee.org/sl/ .
// Copyright © 2007 Xah Lee.
// Permission is granted for use or modification provided this note is intact.

// Particle that simulates a single firework burst

partyOn(){
llParticleSystem([
 PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_EXPLODE,

 PSYS_SRC_MAX_AGE, 0.,
 PSYS_PART_MAX_AGE, 9.,

 PSYS_SRC_BURST_RATE, 20.,
 PSYS_SRC_BURST_PART_COUNT, 500,

 PSYS_SRC_BURST_RADIUS, .1,
 PSYS_SRC_BURST_SPEED_MIN, 3.,
 PSYS_SRC_BURST_SPEED_MAX, 3.,
 PSYS_SRC_ACCEL, <0.0,0.0,-0.8>,

 PSYS_PART_START_COLOR, <246,38,9>/255.,
 PSYS_PART_END_COLOR, <246,38,9>/255,

 PSYS_PART_START_ALPHA, 0.9,
 PSYS_PART_END_ALPHA, 0.0,

 PSYS_PART_START_SCALE, <.3,.3,0>,
 PSYS_PART_END_SCALE, <.1,.1,0>,

 PSYS_PART_FLAGS
 , 0
 | PSYS_PART_EMISSIVE_MASK
 | PSYS_PART_INTERP_COLOR_MASK
 | PSYS_PART_INTERP_SCALE_MASK
 | PSYS_PART_FOLLOW_VELOCITY_MASK
 //| PSYS_PART_WIND_MASK
]);
}

default { state_entry() { partyOn(); } }

Sparkler

// This script is from http://xahlee.org/sl/ .
// Copyright © 2007 Xah Lee.
// Permission is granted for use or modification provided this note is intact.

// Particle that simulates the sparkles from a sparkling wand.

partyOn(){
llParticleSystem([
 PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_EXPLODE,

 PSYS_SRC_MAX_AGE, 0.,
 PSYS_PART_MAX_AGE, .6,

 PSYS_SRC_BURST_RATE, .05,
 PSYS_SRC_BURST_PART_COUNT, 50,

 PSYS_SRC_BURST_RADIUS, 1.,
 PSYS_SRC_BURST_SPEED_MIN, .1,
 PSYS_SRC_BURST_SPEED_MAX, 2.,
 PSYS_SRC_ACCEL, <0.0,0.0,-0.8>,

 PSYS_PART_START_COLOR, <1,1,1>,
 PSYS_PART_END_COLOR, <1,0,0>,

 PSYS_PART_START_ALPHA, 0.9,
 PSYS_PART_END_ALPHA, 0.0,

 PSYS_PART_START_SCALE, <.15,.15,0>,
 PSYS_PART_END_SCALE, <.01,.1,0>,

 PSYS_PART_FLAGS
 , 0
 | PSYS_PART_EMISSIVE_MASK
 | PSYS_PART_INTERP_COLOR_MASK
 | PSYS_PART_INTERP_SCALE_MASK
 | PSYS_PART_FOLLOW_SRC_MASK
 | PSYS_PART_FOLLOW_VELOCITY_MASK
]);
}

default { state_entry() { partyOn(); } }

Rotating Water Sprinkler

// This script is from http://xahlee.org/sl/ .
// Copyright © 2007 Xah Lee.
// Permission is granted for use or modification provided this note is intact.

// a rotating water springler for lawns

partyOn(){
llParticleSystem([
 PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_ANGLE,

 PSYS_SRC_MAX_AGE, 0.,

 PSYS_SRC_BURST_RATE, .3,
 PSYS_SRC_BURST_PART_COUNT, 50,

 PSYS_SRC_BURST_RADIUS, .2,
 PSYS_SRC_BURST_SPEED_MIN, 1.,
 PSYS_SRC_BURST_SPEED_MAX, 5.,
 PSYS_SRC_ACCEL, <0.0,0.0,-1.>,

 PSYS_SRC_ANGLE_BEGIN, 0.9,
 PSYS_SRC_ANGLE_END, 1.,
 PSYS_SRC_OMEGA, <0.,0.,1.>,

 PSYS_PART_MAX_AGE, 4.,

 PSYS_PART_START_COLOR, <1,1,1>,
 PSYS_PART_END_COLOR, <1,1,1>,

 PSYS_PART_START_ALPHA, .7,
 PSYS_PART_END_ALPHA, 0.1,

 PSYS_PART_START_SCALE, <.08,.8,0>,
 PSYS_PART_END_SCALE, <.05,.1,0>,

 PSYS_PART_FLAGS
 , 0
 | PSYS_PART_INTERP_COLOR_MASK
 | PSYS_PART_INTERP_SCALE_MASK
 | PSYS_PART_FOLLOW_VELOCITY_MASK
 | PSYS_PART_WIND_MASK
]);
}

default { state_entry() { partyOn(); } }

Particle trail

// This script is from http://xahlee.org/sl/ .
// Copyright © 2007 Xah Lee.
// Permission is granted for use or modification provided this note is intact.

// This is a bread crumb trail particle. Wear it on top of av's head. When the av moves, it leaves a trail.

partyOn(){
llParticleSystem([
 PSYS_SRC_PATTERN, PSYS_SRC_PATTERN_DROP,
 PSYS_SRC_MAX_AGE, 0.,
 PSYS_SRC_BURST_RATE, .2,
 PSYS_SRC_BURST_PART_COUNT, 1,

 PSYS_SRC_ACCEL, <0,0,0>,

 PSYS_SRC_ANGLE_BEGIN, 0.,
 PSYS_SRC_ANGLE_END, 0.,
 PSYS_SRC_OMEGA, <0.0,0.0,0.0>,

 PSYS_PART_MAX_AGE, 60.,

 PSYS_PART_START_COLOR, <1,0,0>,
 PSYS_PART_END_COLOR, <0,0,1>,

 PSYS_PART_START_ALPHA, 0.7,
 PSYS_PART_END_ALPHA, 0.7,

 PSYS_PART_START_SCALE, <.3,.3,0>,
 PSYS_PART_END_SCALE, <.1,.1,0>,

 PSYS_PART_FLAGS
 , 0
 | PSYS_PART_EMISSIVE_MASK
 | PSYS_PART_INTERP_COLOR_MASK
 | PSYS_PART_INTERP_SCALE_MASK
 //| PSYS_PART_WIND_MASK
]);
}

default { state_entry() { partyOn(); } }

Generic Particle Template

Experiment with this generic template.

// This script is from 
// Linden Scripting Language Tutorial: Particle System
// http://xahsl.org/sl/ls-particles.html
// Copyright © 2007 Xah Lee.
// Permission is granted for use or modification provided this note is intact.

// This is a template for particles.
// tweak the various parameters to get different effects.
// Make sure that decimal numbers stays decimal and integers stay integers.

partyOn(){
llParticleSystem([
 //------------------------------------
 // overall pattern of the whole particles
 // pick one in the following.

 // The pattern EXPLODE is good for fireworks. The DROP would be good for water drops. The PATTERN_ANGLE will burst particles in a pie-shape in the x-plane. Good for example for rainbow. ANGLE_CONE is a cone along the z-axes, good for example for jet exhaust, or water fountain. ANGLE_CONE_EMPTY is like ANGLE_CONE, but where ANGLE_CONE shoots, ANGLE_CONE_EMPTY will not.

 PSYS_SRC_PATTERN,
  PSYS_SRC_PATTERN_EXPLODE
  //PSYS_SRC_PATTERN_DROP
  //PSYS_SRC_PATTERN_ANGLE
  //PSYS_SRC_PATTERN_ANGLE_CONE
  //PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY
 ,
 //------------------------------------
 // THE SHAPE OF EACH PARTICLE

 PSYS_SRC_TEXTURE, "", // invt name, or UUID of a texture

 //------------------------------------
 // parameters for the particle emiter. (units for time are in seconds.)

 // duration of the emitter will be spawning. Use 0. for forever. “60.” is the max.
 PSYS_SRC_MAX_AGE, 0.,

 //frequency of spawning
 PSYS_SRC_BURST_RATE, .9,

 // number of particles per burst
 PSYS_SRC_BURST_PART_COUNT, 4,

// The distance the particle will be created from the emitter.
 PSYS_SRC_BURST_RADIUS, 6.,

 // Particles will fly off at a random speed between min and max. For example, if you want a firework burst such that all sparkles are on the increasingly larger spherical boundary, set the max and min speed to the same value such as “1.0”. If you want the firework sparkles to be inside the spherical boundary as well, use for example “0.1” and “1.0”.
 PSYS_SRC_BURST_SPEED_MIN, 1.,
 PSYS_SRC_BURST_SPEED_MAX, 1.,

 // A force on the particle after they are emitted. Each unit is meter per second. Max is 100. So, to emulate water falling from a sprinkler nozzle, use  <0.0,0.0,-0.8> to emulate a gravity. To emulate smoke being sucked into a tunnel, use a vector with non-zero x and y coordinates.
 PSYS_SRC_ACCEL, <0.0,0.0,-0.8>,

 // The following are for the directions of the particle burst. They are valid if the particle pattern is one of PSYS_SRC_PATTERN_ANGLE, PSYS_SRC_PATTERN_ANGLE_CONE, PSYS_SRC_PATTERN_ANGLE_CONE_EMPTY. The PSYS_SRC_OMEGA will rotate the shooting. Angle starts from the z-axes and are in radians.
 PSYS_SRC_ANGLE_BEGIN, 1.0,
 PSYS_SRC_ANGLE_END, 1.1,
 PSYS_SRC_OMEGA, < 0., 0. , 0.>,

 //------------------------------------
 // parameters that controls the particle sprites (a sprite is a 2D image that always faces the viewer. Particles are sprites.)

 // the age of each particle. Max is 30.
 PSYS_PART_MAX_AGE, 10.,

 // The end color must have PSYS_PART_INTERP_COLOR_MASK on in PSYS_PART_FLAGS
 PSYS_PART_START_COLOR, <1,0,0>,
 PSYS_PART_END_COLOR, <0,0,1>,

 // The ALPHA is transparency, from 0 to 1. 1 means opaque.
 PSYS_PART_START_ALPHA, .8 ,
 PSYS_PART_END_ALPHA, 0. ,

 //scale change. valid values are from 0.031 to 4.0 .
 //must have INTERP_SCALE_MASK on in PSYS_PART_FLAGS.
 PSYS_PART_START_SCALE, <1,1,0>,
 PSYS_PART_END_SCALE, <.1,.1,0>,

 //------------------------------------
 // miscellaneous behaviors controlled by PSYS_PART_FLAGS
 PSYS_PART_FLAGS
 , 0

 // glows. Basically brighter.
 | PSYS_PART_EMISSIVE_MASK

 // change particle color. Makes PSYS_PART_START_COLOR, PSYS_PART_END_COLOR work.
 | PSYS_PART_INTERP_COLOR_MASK

 // make it change size during its life. makes PSYS_PART_START_SCALE, PSYS_PART_END_SCALE work.
 | PSYS_PART_INTERP_SCALE_MASK

 // make particles bounce off emiter's z-axis height, works only when the particle falls after bust.
 | PSYS_PART_BOUNCE_MASK

 // The PSYS_PART_FOLLOW_SRC_MASK makes the emitted particle's positions follow the emiter (disables PSYS_SRC_BURST_RADIUS). If not set, then particles once emitted outside of the PSYS_SRC_BURST_RADIUS will flow by themselves. For example, a blinking LED on a watch should have this set. Smokes from a cigerette should not have this set.
 | PSYS_PART_FOLLOW_SRC_MASK

 // Orient the particle sprite (the image) with the emiter's bursting direction. For example, a rotating water sprinkler should have this set.  But if your sprite is textual such as “I Love You”, then it should not have this set.
 | PSYS_PART_FOLLOW_VELOCITY_MASK

 // straight line to target (cancels PSYS_SRC_ACCEL, PSYS_SRC_BURST_RADIUS)
 //| PSYS_PART_TARGET_LINEAR_MASK

 // make it blown by wind
 //| PSYS_PART_WIND_MASK

 //make particles follow a target specified at PSYS_SRC_TARGET_KEY
 //PSYS_PART_TARGET_POS_MASK

 //------------------------------------
 // following behavior. (needs PSYS_PART_FOLLOW_VELOCITY_MASK on)

 //PSYS_SRC_TARGET_KEY,llGetKey(),
]);
}

default { state_entry() { partyOn(); } }

If you like to experiment with particles, try Xah Particle Maker. If lets you set particle parameters by touch-panels or typed commands, and see the particles update in real time. This saves you a lot time in the edit-compile loop.

Reference:

Want to dash through walls?
Try Xah Tele-Dasher!
2007-03