I've been working in some visible light effects.
You can see these in action in my
Cathedral Level in this Showcase thread. The scripts are relatively simple.
The lightbeamFX is suppossed to be used with an image of lightbeams, going tru a window. The script basically fades the sprite away when the camera gets close to its PLANE, thus making the effect more subtle and real than just allowing the camera to break tru the sprites.
This can be controled by the fade_distance skill, which is how close the camera is for the sprite start fading. if you don't want it to fade, set this to 0.
The lightdustFX is suppossed to be applied to cloud-like images, which should be aligned to match the light entering tru a window. (Or around a lava pit, or wherever you want them).
It sets the sprites to face the camera by default. It fades the sprites away when the camera gets closer, and it also adds a very slow time-based rolling to these clouds, to give the very subtle dust-twirling effect.
The fade_distance skill works the same as lightbeam. Additionally you can set a positive or negative roll speed. If you leave it as zero, the script will assign a random value (very slow, CW or CWW).
Here is the script:
Code:
//light effects (c) 2005 Emilio Le Roux
//Free for personal or commercial use
//used by lightbeam and lightdust effects
DEFINE max_alpha, SKILL1;
DEFINE fade_distance, SKILL2;
DEFINE face_camera, flag1;
DEFINE pan_only, flag2;
DEFINE roll_speed,SKILL3;
/////////////////////////////////////////
// LIGHTBEAM FX
// Add this behavior to a light beams TGA image. No alpha channel needed.
// uses max_alpha,fade_distance,face_camera,pan_only
// skill1: max_alpha 25.0
// skill2: fade_distance 500.0
// flag1: face_camera 0
// flag2: pan_only 0
ACTION lightbeamFX
{
me.alpha=me.max_alpha;
me.bright=on;
me.transparent=on;
me.passable = on;
//user should set ambiance and other desired flags/values in WED
//set orientation style
if (me.face_camera)
{
my.oriented = off;
if (me.pan_only)
{
my.facing = off;
}
else
{
my.facing = on;
}
}
else
{
my.oriented = on;
my.facing = off;
}
var vnormal[3];
var fadefactor;
while (1)
{
if (me.fade_distance > 0)
{
//calculate sprite normal after its angle
vec_for_angle(vnormal,me.pan);
//calculate distance from camera to plane of the sprite (dot product)
fadefactor = vec_dot( vnormal.x, Vector(camera.x-me.x,camera.y-me.y,camera.z-me.z));
//convert the distance to a fade factor
fadefactor = min( abs(fadefactor) * me.max_alpha / me.fade_distance, me.max_alpha);
me.alpha = fadefactor; //set transparency
}
wait(1); //(could be wait(more) for speed?
}
}
/////////////////////////////////////////
// LIGHTDUST FX
// Add this behavior to several cloud-like TGA images. No alpha channel needed.
// uses max_alpha,fade_distance,face_camera,pan_only,roll_speed
// skill1: max_alpha 25.0
// skill2: fade_distance 500.0
// skill3: roll_speed 0.0
// flag1: face_camera 1
// flag2: pan_only 0
ACTION lightdustFX
{
my.passable = on;
me.transparent = on;
me.bright = on;
me.alpha = me.max_alpha;
//set orientation style
if (me.face_camera)
{
my.oriented = off;
if (me.pan_only)
{
my.facing = off;
}
else
{
my.facing = on;
}
}
else
{
my.oriented = on;
my.facing = off;
}
if (me.roll_speed == 0)
{
// set roll speed for this sprite to a very low pos/neg value
me.roll_speed = random(2)-1;
}
while(1)
{
me.roll += me.roll_speed*time; //roll this sprite
if (me.fade_distance>0)
{
//fade this sprite from max_alpha to zero, as it comes close to camera by fade_distance value.
me.alpha = min (me.max_alpha, vec_dist(camera.x,me.x) *me.max_alpha / me.fade_distance);
}
wait(1); //could wait more?
}
}
In both actions, the max_alpha skill defines the maximum opacity. I recommend values from 10 to 25. You have to be careful, since the sprites ADD to the background, so too many stacked sprites with a high alpha value will shine too much.
Emilio