This samples shows us how to render a 3D lens flare with OpenGL. A lens flare effect go with a light source. Before divide into the render part, there are several things that need to be addressed first.
1) How to make sure whether a light source in the view frustum or not;
2) Whether a light source is occluded by other objects or not;
3) How to build a view frustum given by the view matrix and projection matrix;
4) After all above problems solved, then try to solve the position of the 3D lens flare.
Point check in view frustum
There is no frustum structure in the OpenGL, what we could get are some matrixes: view matrix & projection matrix. The view frustum used here is just an volume en-closed by 6 clip planes. So the first question is how to build those 6 clip plane given by the matrix.
Right clip plane : W – X;
Left clip plane : W + X;
Bottom clip Plane : W + Y;
Top clip plane : W – Y;
Far clip plane: W – Z;
Near clip plane: W + Z;
As you see, the function that to create clip planes is very easy. It is very easy to understand if you take the matrix as an identity matrix.
After you get those 6 clip planes, the next step is to go though all those planes and to check whether this point locate in front of all planes.
Occlusion Testing with gluProject command
After we make sure that the light source locate in the view frustum, we need to further make sure that the whether this position occluded by other objects or not.
With gluProject function, we could project a 3d position into 2d window position with a completely depth value as one in the depth buffer. We could check this depth value with depth buffer one given by the screen position. The following are the code:
glGetIntegerv (GL_VIEWPORT, viewport); //get actual viewport glGetDoublev (GL_MODELVIEW_MATRIX, mvmatrix); //get actual model view matrix glGetDoublev (GL_PROJECTION_MATRIX, projmatrix); //get actual projiection matrix // this asks OGL to guess the 2d position of a 3d point inside the viewport gluProject(p.x, p.y, p.z, mvmatrix, projmatrix, viewport, &winx, &winy, &winz); flareZ = winz; // we read back one pixel from th depth buffer (exactly where our flare should be drawn) glReadPixels(winx, winy,1,1,GL_DEPTH_COMPONENT, GL_FLOAT, &bufferZ); // if the buffer Z is lower than our flare guessed Z then don't draw // this means there is something in front of our flare if (bufferZ < flareZ) return true; else return false;
Calculate the 3D Lens Flare effect
Remember the 3D lens flare effect goes with the light source position. What we need to do is find the light source position and offsets (based on the camera view direction) for those series of alpha blending glow textures.As the diagram details, the bold and dark green line are the areas that used to draw those glow textures. For more details about how to set those offsets and steps, the source code could be found here.