halo / lens flare

i also posted this in the beginner´s forum but it´s not quite a beginner´s topic:

i think this is a bit of a non-trivial problem:

i´ve got a scene with several objects that represent light sources, like headlights etc. these are not actually openGL light sources, i just bright cubes or whatever. what i want to do is lay a halo effect on each of these light sources: you see this in various games, like you would have a star-shaped flare emitted by a car´s brake lights, streetlights, etc… can also be seen in the N64 game “Perfect Dark” quite frequently
basically, i only need to draw a semi-transparent bitmap overlaid on each lightsource. the problem is, how do i determine where the sources (and IF) they are actually drawn? i must only draw the halo if a lightsource is visible otherwise it looks wrong.
basically, it´s the same problem as with a lens flare, you want to know when to draw the flare because the light source is visible, and when to omit it.

i´ve got one approach, but am not sure whether this might work:

  • set a certain value in the stencil buffer if a lightsource is drawn
  • set another value if anything else is drawn
  • finally, check where there are “source” values in the stencil buffer and draw the halos there.
    this might be very slow since i need to directly access the stencil buffer that way.

has anyone some experience with haloing / lens flares, or knows a good net resource?

regards

eik

Put your lightflare bitmaps at the same position as your model, or slightly infront of them, then let the zbuffer handle it all.

Treat your effects as true 3D objects and render them when you render your objects to be affected, instead of just putting them on screen afterwards.

Just a thought.

Well, you should be able to figure out where to look in your buffer based on the screen coordinates of the light “source”. If you write to a auxilary buffer and glReadPixels(?) a rectange in the area where the object is known to be, then you should be able to count up pixels relatively quickly. Or you can all-or-nothing it with a single pixel read.

But the key is to use the info you have about the object’s location to speed things up.

If you put the flare in 3d space, it’ll look funny if partially occluded. Those fx don’t work that way.

Aha. I see the problem.

Alas, I have no solution.

I think I would do vector-bounding volume intersections. If every object has one or more bounding volumes that are a simplified representation of its shape, a few vector-box and/or vector-sphere intersection tests should be enough to determine if an object occludes a light source.

Originally posted by mv:
Well, you should be able to figure out where to look in your buffer based on the screen coordinates of the light “source”.

ok i´ve programmed quite a bit with openGL but i´ve never quite got the idea of screen coordinates. what are they and how do i get them?

Screen coordinates are the 3d positions of your objects, pushed through the view/model matrices, and projected onto your viewport.

If you grab the matrix right at your object call, I think indices 12-14 are your x,y,z positions in camera space. I think. You can get screen space by projecting the 3D coordinates onto your view-plane.

I think it’s:
screen_x = -x / z;
screen_y = -y / z;

There may be a scale factor based on your viewport scale and the sign may be inverted, but that’s the jist of it…

You’ll need the screen space coords for your flare anyway to position it, so store them somewhere during your draw routine, then go back and check em…

erm… how do i grab the transformed matrix? i know the glLoadMatrix() but there´s no glReadMatrix()…?

It’s a generic glGet call…

GLfloat matrix[16];
glGetFloatv(GL_MODELVIEW_MATRIX, matrix);

You have to have done all your transforms in the MODELVIEW tho (as opposed to PROJECTION and MODELVIEW).

Use gluUnproject/gluProject to transform 2D/3D points from Screen to Space.
Then it’s easy to check if your 3D light source is inside the viewport.
Lens flare have to be drawn in a 2D Overlay layer in order to avoid overlapping/intersection with 3D objects.

Regards.

thanks a lot, i get the idea how to do it now!

unfortunately, the GetMatrix stuff always gets me very large negative values if i try it, no matter at what point in the rendering pipeline i query the matrix stack, the result is always the same…

is there something special i should take care of?