Previous: 2.c Making sparks out of particles
In this lesson, we will see how to construct a stationary laser beam. Notice the word "stationary". This is not a script to make a light saber or lasers coming out of a speeding spaceship. Well, at least not before being heavily modified anyway (I will come back to this point below). However, this effect is perfectly adequate for a laser barrier for instance. Most importantly it illustrates how one can build a seemingly "solid" or "unified" object, such as a beam, from a minimal number of individual particles. The mathematical formulas which do this are then easily generalized to particle trails.
Here is the action which emits the laser (see lesson3.wdl):
var velocity; action a_min_laser { // define a direction/velocity for the laser velocity.x = 50; velocity.y = 0; velocity.z = 0; // loop which generates the photons while(1) { if (key_1) { // create the particles effect(min_photon,1,my.x,velocity.x); } wait(1); } }
and the function attached to each particle or photon of the beam:
var photon_size = 5; function min_photon() { if (my.lifespan==80) { my.size = photon_size; my.bright = on; my.flare = on; my.alpha = 100; my.move = on; my.red = random(40); my.green = 255; my.blue = random(40); my.gravity = 0; my.lifespan = 30; } }
This is almost identical to the code we used for the minimal fountain in lesson 2, except that instead of launching particles randomly in the air, we give to all of them the same velocity vector, pointing straight along the x axis and with a speed of 50 quants/tick. Like in the minimal code before, one particle is created at every frame, so every time ticks. Let us run the included level lesson3.wed and press the "1" key: we get what is on Figure 3.1 below.
Figure 3.1: Laser 'beam' with the minimal code: the beam looks like a dotted line as there are gaps between the particles emitted at each frame.
Hum! Well, this is not exactly Star Wars Episode II quality to say the least. The result is an 'interesting-looking', green, dashed line made of little green squares, which seems to fluctuate about a bit. What is happening here?...
Well, first, the green little squares are there because you'll note I did not specify a bitmap in the function min_photon() attached to the particles of the beam. 3DGS therefore represents them by default with little color squares. That is easily fixed and we will do that later on.
What is more bothersome is that there are huge gaps between the particles in the beam. And the faster the particles or the slower the frame rate, the larger these gaps become. Why is that?
What we are seeing is a direct result of equation (2.6) which illustrated that in 3DGS, particles (and any entities for that matter) move in discrete steps velocity*time at each frame. In the present case, the position of each particle obeys the equation:
my.x(t+time) = my.x(t) + velocity.x*time (3.1)
with velocity.x = 50; The y and z coordinates of the particles (my.y and my.z) are constant in time since the beam points in the x direction. With every particle jumping along the x direction 50*time quants at a time, what we get is a slightly fluctuating bunch of dots with 50*time quants gaps between them (see also top of Figure 3.3). What can we do to fix the problem?
Some of you might say "Well, just switch on the beam flag and it will fill the gaps".
Sure that would work but I'll resist that temptation for 2 reasons. First: convenience. The beam effect is only available in the commercial and professional editions. :-( I'm sure people using the more affordable editions would be willing to do a little math to get beam effects.
Second: control. The beam flag works fine but one has little control over the detail of the effect. What if I want the color of the beam to change depending on the distance to the laser canon, or try out even more complex effects? What if the frame rate drops just a little too much when beam is on? No fine adjustments are available (besides fiddling with the particle's speed) to find a compromise. These are the reasons that drove me to develop some of the equations presented in this tutorial when preparing the Pyrotechno! demo. In the end, they worked so well that I removed all beam flags altogether, making the fireworks run equally well on all 3DGS editions.
Other not so appealing solutions to our problem would be to increase the size of the particles, lower their speed to a crawl or lower the resolution to Commodore 64 levels to increase frame rate as much as possible. All these will narrow the gaps. The first solution will fill the gap but our laser beam would look more like a force field than a sharp beam. The second is alright also but not very exciting. We'll just forget about the third one. :-)