Intro:
Lens flares are artifacts caused in the real world by internal reflections
of light within cameras. For some reason they have caught on as a 'nice
thing to do' within games - even though the human eye never sees them.
I present here a simple method for creating this effect - and I expect
virtually anyone with some time on his or her hands to produce a better
demo than me - my graphics are rudimentary and repetitive, but as proof
of concept shouldn't go far wrong.
Method:
I use (ack!) overlays. My lensflare object creates one overlay for each
artifact of a lens flare. I have not tested multiple lensflares but
they should work (touch wood).
Each artifact can have it's texture specified, as well as it's scale,
and it's distance along the 'lensflare vector'. By this I mean that
lens flare artifacts are placed on a straight line that passes from
the position of the light source through the center of the screen.
Lens flares appear with my code only when the following conditions are
satisfied::
There are no
objects between the camera position and the light position (modelsUnderRay
- not the quickest code ever)
The angle between
the camera's Z axis (IE looking forward) and the vector from the camera
to the light are LESS than half the camera's field of view. This means
the lens flare disappears as you turn away from the light source.
Lens flares fade in
and out according to how far from the center of the viewport the light
source is. When directly in front, the lens flares are at maximum intensity.
This fades out linearly until they are invisible where the angle between
the camera's Z axis (IE looking forward) and the vector from the camera
to the light equals half the camera's field of view.
In Practice:
There are several options and settable features including:.
You can lock
the lens flare onto either an actual light, or a model representing
a light.
You might want to have a model representing a light to make the light
source 'visible'. The demo below works on this basis. Obviously the
yellow sphere isn't giving out light, it is merely positioned where
the light source is.
To lock the lensflare onto a model, use:
tRect is the rectangle defining the 3D sprite's rect on the stage.
tWorld is the member containing the 3D world.
tCamera is a direct reference to the camera the lensflare is associated
with.
tLight is a direct reference to the light the lensflare is to come
from, or
tLightModel is a direct reference to the model the lensflare is to
come from.
It should be noted that no matter how big the visual size of tLightModel
- only a path from the camera to the model's exact origin is tested
against.
Updating the
lensflare each frame:
If the camera has moved, objects in the scene are moved, the light
has moved, or for any other reason the lens flare needs recalculating,
then call the following code:
goLensFlare.Update()
where goLensFlare is the object reference to the lensflare parent
script - stored when created.
Setting up the
lensflare
Within the lens flare parent script's new() handler is a section that
sets a property called plOverlays. Editing this is the key to setting
up your own lens flare artifacts. Here you can specify their position,
what texture they use, and their scale. I did not make this a parameter
to pass when instantiating the script simply because it would be a
long value to set-up. I would suggest setting this here as you want
lensflares to appear - it would be extremely rare to have more than
one 'type' of lensflare since they are defined by the viewing camera.
The format is as follows:
Each sublist within plOverlays represents 1 artifact. A sublist has
the format:
[tPositionOnLensFlareVector, tMemberName, tScale]
where:
tPositionOnLensFlareVector can be any floating point value. 1.0 represents
exactly where the light is onscreen. -1.0 represents the mirror value
of this, when reflected about the exact center of the view port. Any
and all other values are permissable.
tMemberName is the name of the bitmap member to use as the texture
for this artifact.
tScale is the scale of the artifact - 1.0 is it's original size. 0.5
is half, 2.0 is double etc. Again all values are permissable, but
try to refrain from making this too big otherwise slowdown may occur.
Also you can have as many or as few artifacts as you choose - simply
have one sublist per artifact and delete or add extra ones as required.
Updates:
Several items have changed:.
The lensflare
artifacts now fade out as the light source gets further away from
the center of the view. Thanks to Christophe Leske for how to do this.
The order of
visibility checks has been swapped from:
modelsUnderRay() -> Angle between
vectors
to
Angle between vectors -> modelsUnderRay()
This is to make sure the costly modelsUnderRay() check is only called
when absolutely necessary.