14. OpenGL Fog (Version 2.0)
Introduction to OpenGL Fog
Fog is a fantastic visual effect that helps add depth and realism to your 3D scenes. It’s a staple in games and simulations, often used to suggest vast distances, obscure distant objects, or create an atmospheric mood. In this tutorial, we’ll cover the basics of creating fog in OpenGL, keeping things simple and easy to understand.
There are a few key steps to setting up fog:
1. Enable depth testing to ensure the fog interacts correctly with 3D objects.
2. Enable fog in OpenGL.
3. Choose a fog mode.
4. Set the fog color.
5. Define the fog density.
6. Optionally, specify how smooth or optimized the fog effect should appear.
We’ll stick to the essentials for now, but you’ll see how to tweak these parameters to get the best results for your scene.
Getting Started: Fog Variables
Before we start coding, we need to define a couple of variables for the fog’s properties. Here’s what I’ve used:
GLfloat density = 0.3; // Fog density: how thick the fog is GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1.0}; // Fog color: a medium grey
What does this mean?
– The fog color is defined using four components: red, green, blue, and alpha (opacity). In this case, I’ve set it to a neutral grey (`R = 0.5, G = 0.5, B = 0.5`).
– The density controls how thick or intense the fog is. A value of `0.3` is relatively thick, as you’ll see when we run the application.
Enabling Fog in OpenGL
Once we’ve defined the fog properties, we can set it up in OpenGL. Here are the steps:
1. **Enable fog**
Use `glEnable(GL_FOG)` to turn on OpenGL’s fog functionality.
glEnable(GL_FOG);
2. **Set the fog mode**
OpenGL supports several fog modes:
– `GL_LINEAR`: Fog increases linearly between the start and end distances.
– `GL_EXP`: Fog increases exponentially based on distance.
– `GL_EXP2`: Fog increases exponentially with a squared factor for a more natural look.
For this tutorial, I’ve chosen `GL_EXP2` because it often looks the best:
glFogi(GL_FOG_MODE, GL_EXP2);
3. **Set the fog color**
This determines the color of the fog and how it blends with the objects in the scene.
glFogfv(GL_FOG_COLOR, fogColor);
4. **Set the fog density**
Control how quickly the fog becomes opaque:
glFogf(GL_FOG_DENSITY, density);
5. **Optimize fog rendering**
The `glHint` function lets you balance quality and performance. For the best visual results, use `GL_NICEST`:
glHint(GL_FOG_HINT, GL_NICEST);
What Does It Look Like?
With this setup, the fog will gradually thicken as objects move further away from the camera. The density of `0.3` creates a noticeable effect, but you can experiment with higher or lower values to suit your scene. For example:
– `0.1`: Very light fog, barely noticeable.
– `0.5`: Dense fog, obscuring objects quickly.
The Full Code
Here’s the complete code for a simple OpenGL application that demonstrates fog on a rotating cube. Paste this into your project to see it in action:
#include <GL/gl.h> #include <GL/glut.h> GLfloat angle = 0.0; GLfloat density = 0.3; // Fog density: relatively thick GLfloat fogColor[4] = {0.5, 0.5, 0.5, 1.0}; // Fog color: medium grey // Draw a rotating cube void cube(void) { glRotatef(angle, 1.0, 0.0, 0.0); // Rotate on X-axis glRotatef(angle, 0.0, 1.0, 0.0); // Rotate on Y-axis glRotatef(angle, 0.0, 0.0, 1.0); // Rotate on Z-axis glColor3f(1.0, 0.0, 0.0); // Cube color: red glutSolidCube(2); } // Initialize fog and OpenGL settings void init(void) { glEnable(GL_DEPTH_TEST); // Enable depth testing glEnable(GL_FOG); // Enable fog glFogi(GL_FOG_MODE, GL_EXP2); // Fog mode: exponential squared glFogfv(GL_FOG_COLOR, fogColor); // Set fog color glFogf(GL_FOG_DENSITY, density); // Set fog density glHint(GL_FOG_HINT, GL_NICEST); // Optimize fog appearance } // Render the scene void display(void) { glClearColor(0.0, 0.0, 0.0, 1.0); // Clear screen to black glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); gluLookAt(0.0, 0.0, 5.0, 0.0, 0.0, 0.0, 0.0, 1.0, 0.0); // Camera setup cube(); glutSwapBuffers(); angle++; // Increment rotation angle } // Handle window resizing void reshape(int w, int h) { glViewport(0, 0, (GLsizei)w, (GLsizei)h); // Set viewport glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(60, (GLfloat)w / (GLfloat)h, 1.0, 100.0); // Perspective projection glMatrixMode(GL_MODELVIEW); } // Main function int main(int argc, char **argv) { glutInit(&argc, argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA | GLUT_DEPTH); glutInitWindowSize(500, 500); // Window size glutInitWindowPosition(100, 100); // Window position glutCreateWindow("OpenGL Fog Example"); // Window title init(); // Initialize fog and settings glutDisplayFunc(display); // Render function glutIdleFunc(display); // Animation glutReshapeFunc(reshape); // Handle window resizing glutMainLoop(); // Enter the event loop return 0; }
What’s Next?
This tutorial covered the basics of OpenGL fog, but there’s a lot more you can do. For example:
– Set start and end distances for linear fog.
– Experiment with different fog colors and densities.
– Use fog to simulate weather effects like mist, haze, or smog.
I’ll dive into these advanced topics in the next fog tutorial. For now, experiment with the parameters and see what works best for your scenes.
If you run into any issues, feel free to email me at swiftless@gmail.com. Happy coding!
can you tell something about GL_FOG_INDEX
where and why it is used and for what…
fog is deprecated in opengl 3.1 and above.
afortunately it’s simple to do the fog effect in vetex/fragment shaders.
Hi, these tutorial are really good 🙂 they’re simple too 😉 However, I see you don’t know what the fourth parameter of the fog color stands for. It is simply the Alpha value, in fact you pass for parameters, R(ed), (G)reen, (B)lue and (A)lpha. I’m basing on the Red Book, “OpenGL Programming Guide”, Sixth Edition, page 265.
Hey Michael,
Thanks. They were initially designed to be super simple, showing off each method. Careful with what you say I don’t know though 😉 These tutorials (Version 1.0) are about 5 years older than the post date, the post date is just when it was moved over to a WordPress back end. These were effectively written by me at about the age of 13-15.
You’re definitely correct about the fourth parameter being the Alpha value. That holds true in everything colour related, where the older versions of OpenGL (from the time this was written) allowed you to set either RGB or RGBA, the newer versions of OpenGL, 3.x and 4.x assume you handle all colours yourself inside of your shaders. Because you were allowed to skip the A value in the fixed pipeline, I believe I skipped it in a few of these tutorials. I don’t mention Alpha values until a specific tutorial.
Cheers,
Swiftless
@”A Man”: A simple piece of code I took from another OpenGL tutorial limits the frame rate:
bool limitFpsTo(int rate){
static float last = GetTickCount() * 0.001f;
static float elapsed = 0.0f;
float currect = GetTickCount() * 0.001f;
float delta = currect – last;
float FPS = 1.0f/rate;
elapsed+=delta;
last=currect;
if (elapsed>FPS)
{
elapsed -=FPS;
return true;
}
return false;
}
If you place the buffered keyOperations() function introduced in Tutorial 3 inside the if(limitFpsTo) in the display() function the speed should be fixed.
Hey!
i have prob. with this tut. I have lighting too and when try fog everything drawn becomes black. I can’t understand why…
Do u know what problem might be?
Object too far away? Haven’t set your “fogColor” array var up with 0.5,0.5,0.5,1 (four values)?
Also try “glClearColor(0.5, 0.5, 0.5, 1);” prior — makes the background gray to match the fog. Otherwise, yes, yr background will be black.
on my computer the cube rotate very fast so i changed
this
angle ++;
to
angle += 0.01
Hi A man,
Depending on the speed of your machine, you will always have to change this. To make it constant on every machine, you need to use some time-based techniques. Such as incrementing angle depending on how much time has passed since the last frame.
Thanks,
Swiftless
Heya, cool tutorials, keep them up!
btw, I think the fourth value in your fog color is the alpha value, obviously it will only make a change if you have blending enabled. Could be interesting to see if it blends with your glClearColor aye? 🙂
Hey, nice tutorials. On tutorial 14 “OpenGL Fog” The intro is repeated twice. Just so you know.
Thanks for the heads up Ted, I’ll fix that up.
Cheers,
Swiftless