OpenGL Fog
by Luigi Rosso · in Torque Game Engine · 04/15/2004 (5:17 pm) · 11 replies
Hello,
I've implemented a simpler, hardware friendlier, terrain in Torque using static prebuilt and tiled index buffers to render it using vertex buffer objects (loads the data from a normal Torque terrain file). While doing this, I enabled OpenGL fog to do some tests with "simple" fog (no fog volumes) but the results were all wrong, as if the wrong camera space direction component (which would traditionally be the depth, z, axis in OpenGL) were being used in the fog calculations. I don't know how OpenGL calculates the depth of the fragment to fog (I don't think it's per pixel but interpolated per vertex, so it's likely not using the depth buffer, but I may be wrong) but I fear it has to do with Torque's 3DStudio style coordinate system (with the z axis being height and the y axis pointing into the screen) which differs from OpenGL's native one.
Does anyone know of a work around to get OpenGL's fog working? I know it's not a pressing issue (the engine has fine volumed fog as well) but we may be developing a project for a very specific platform where knowing this may be helpful.
Thanks for reading!
I've implemented a simpler, hardware friendlier, terrain in Torque using static prebuilt and tiled index buffers to render it using vertex buffer objects (loads the data from a normal Torque terrain file). While doing this, I enabled OpenGL fog to do some tests with "simple" fog (no fog volumes) but the results were all wrong, as if the wrong camera space direction component (which would traditionally be the depth, z, axis in OpenGL) were being used in the fog calculations. I don't know how OpenGL calculates the depth of the fragment to fog (I don't think it's per pixel but interpolated per vertex, so it's likely not using the depth buffer, but I may be wrong) but I fear it has to do with Torque's 3DStudio style coordinate system (with the z axis being height and the y axis pointing into the screen) which differs from OpenGL's native one.
Does anyone know of a work around to get OpenGL's fog working? I know it's not a pressing issue (the engine has fine volumed fog as well) but we may be developing a project for a very specific platform where knowing this may be helpful.
Thanks for reading!
About the author
#2
I simply setup the frustum using either setupBaseProjection()/setupObjectProjection() based on state info, then I apply the render transform on the modelview matrix. The object renders perfectly fine (identical positions to Torque's terrain) it's just the fog which is off.
04/16/2004 (4:00 am)
I don't do anything particular in setting up the transformations. I had this running in a small testbed application of my own earlier and it worked fine.I simply setup the frustum using either setupBaseProjection()/setupObjectProjection() based on state info, then I apply the render transform on the modelview matrix. The object renders perfectly fine (identical positions to Torque's terrain) it's just the fog which is off.
#3
04/16/2004 (11:43 am)
Hmm... Crazy. I dunno. :)
#4
Maybe I should post some pictures of what's going on...
04/16/2004 (3:40 pm)
I was pretty stumped too :) That's why I was considering Torque's coordinate system as a possible "reason" as to why this is happening.Maybe I should post some pictures of what's going on...
#5
04/16/2004 (5:05 pm)
That could be helpful.
#6
What basically seems to be happening is that the fog is being applied relative to the camera's viewing plane instead of the distance from fragment to camera.
Load up the images in sequence (in a separate browser window) and go back and forth between the 5 and you should see what I mean. I made the fog red to make it easy to see, I also set the fog min and max distances close so the effect is more prominent.
For lack of a more technical explanation: the fog is being applied on the lower and upper part of the screen with a non fogged "band" in the middle. You can see it quite easily on the first shot were I'm looking straight down. Also, in the fourth one you can see it practically on the horizion line were the mountain peak above it is totally fogged out, the base is not, and then as you get closer to the camera the fog increases. In the next shot (looking a little further up) the mountain peak is no longer fogged out.
I'm using linear fog, I've tried different equations but always get variations of the same problem.
Fog 1
Fog 2
Fog 3
Fog 4
Fog 5
04/17/2004 (6:26 am)
It's hard to show this with static images.What basically seems to be happening is that the fog is being applied relative to the camera's viewing plane instead of the distance from fragment to camera.
Load up the images in sequence (in a separate browser window) and go back and forth between the 5 and you should see what I mean. I made the fog red to make it easy to see, I also set the fog min and max distances close so the effect is more prominent.
For lack of a more technical explanation: the fog is being applied on the lower and upper part of the screen with a non fogged "band" in the middle. You can see it quite easily on the first shot were I'm looking straight down. Also, in the fourth one you can see it practically on the horizion line were the mountain peak above it is totally fogged out, the base is not, and then as you get closer to the camera the fog increases. In the next shot (looking a little further up) the mountain peak is no longer fogged out.
I'm using linear fog, I've tried different equations but always get variations of the same problem.
Fog 1
Fog 2
Fog 3
Fog 4
Fog 5
#7
04/17/2004 (9:24 am)
Hmm... That's very odd. I think it's probably a transform issue. More than that I can't say. In my experience you just have to triple check your math and assumptions till the problem goes away.
#8
Thanks for the help!
// EDIT: is there any way to get line breaks working properly in code tags? The code looks really messy like this...
04/17/2004 (10:24 am)
Here's my frustum setup, fog, and transformation code:// state is a SceneState pointer
// rimage is a SceneRenderImage pointer
RectI viewport;
glMatrixMode(GL_PROJECTION);
glPushMatrix();
dglGetViewport(&viewport);
GLfloat fogColor[4];
fogColor[0] = 255;//state->getFogColor().red;
fogColor[1] = 0.0f;//state->getFogColor().green;
fogColor[2] = 0.0f;//state->getFogColor().blue;
fogColor[3] = 1.0f;
glEnable(GL_FOG);
glFogi(GL_FOG_MODE, GL_LINEAR);
glHint(GL_FOG_HINT, GL_NICEST);
glFogfv(GL_FOG_COLOR, fogColor);
glFogf(GL_FOG_DENSITY, 0.35f);
glFogf(GL_FOG_START, 0.0f);//state->getFogDistance());
glFogf(GL_FOG_END, 50.0f);//state->getVisibleDistance());
if (state->isTerrainOverridden() == false) {
state->setupObjectProjection(this);
} else {
state->setupBaseProjection();
}
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
dglMultMatrix(&mRenderObjToWorld);
glScalef(mObjScale.x, mObjScale.y, mObjScale.z);
F64 frustumParam[6];
dglGetFrustum(&frustumParam[0], &frustumParam[1],
&frustumParam[2], &frustumParam[3],
&frustumParam[4], &frustumParam[5]);
MatrixF cameraToObject;
dglGetModelview(&cameraToObject);
cameraToObject.inverse();
Point3F osCamPoint(0, 0, 0);
cameraToObject.mulP(osCamPoint);
sgComputeOSFrustumPlanes(frustumParam,
cameraToObject,
osCamPoint,
m_Frustum[FRONT],
m_Frustum[LEFT],
m_Frustum[RIGHT],
m_Frustum[BOTTOM],
m_Frustum[TOP]);
// CODE REMOVED FOR SIMPLICITY
// ... cull blocks
// ... enable/setup states, pointers, buffers
// ... render
// ... disable buffers, pointers, states
glDisable(GL_FOG);
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
dglSetViewport(viewport);Thanks for the help!
// EDIT: is there any way to get line breaks working properly in code tags? The code looks really messy like this...
#9
I see nothing immediately wrong, but that doesn't mean there isn't anything wrong.
04/17/2004 (3:25 pm)
Looks readable to me.I see nothing immediately wrong, but that doesn't mean there isn't anything wrong.
#10
04/18/2004 (7:51 am)
Thanks for support anyway, most appreciated. I'll try with some simpler objects and see if I can find out what's cuasing this behaviour.
#11
But the strange thing is that the verts are in the correct spot.
Note: I'm currently working in Dracer codebase, which is a bit of a different beast.
05/03/2007 (7:56 am)
Ah, this is my exact issue. It appears as though the GL Fog is not only based on Z, but also on screen coords where the center of the screen adds to the screen value.But the strange thing is that the verts are in the correct spot.
Note: I'm currently working in Dracer codebase, which is a bit of a different beast.
Associate Kyle Carter