Fog with pixel shader (arb_fragment_program)?

Hello!
I try to add fog in a scene that is rendered with a pixel shader (arb_fragment_program)… but I cant use Opengl fog cause the shader bypass the fixed pipeline. any idea how can i implemet fog within a arb fragment program? I have tried some “formulas” but none of this worked right! :frowning:

thank you!

If you are using a vertex shader you need to calculate the fog coordinate like so:

vec4 eyePos = gl_ModelViewMatrix * gl_Vertex;
gl_FogFragCoord = abs(eyePos.z/eyePos.w);

then in your fragment shader you would use this fog coordinate to calculate a per-pixel fog factor:

// Linear fog
float4 fogFactor = (gl_Fog.end - gl_FogFragCoord) * gl_Fog.scale;
// Exp fog
float4 fogFactor = exp(-gl_Fog.density * gl_FogFragCoord);
// Exp2 fog
float4 fogFactor = exp(-pow((gl_Fog.density * gl_FogFragCoord), 2.0));

which you would then clamp to the [0, 1] range and use to lerp between your fog color and input color:

fogFactor = clamp(fogFactor, 0.0, 1.0);
gl_FragColor = mix(gl_Fog.color, gl_Color, fogFactor);

If you are using ARB_fragment_program it is even easier, you can just specify the ARB_fog_linear, ARB_fog_exp, or ARB_fog_exp2 OPTION at the top of your program and the driver will do the fog computation for you:

!!ARBfp1.0
OPTION ARB_fog_linear;
MOV result.color, fragment.color;
END

you rock man! thanks! i will try it tomorow! i need to sleep now!
thank you!

heys. I try it! I just add the line: “OPTION ARB_fog_exp2;” and i setup the OpenGL fog Like this:

glFogi(GL_FOG_MODE, GL_EXP2);
glFogfv(GL_FOG_COLOR, fogColor);
glFogf(GL_FOG_DENSITY, 0.025f);
glHint(GL_FOG_HINT, GL_NICEST);
glFogf(GL_FOG_START, 10.0f);
glFogf(GL_FOG_END, 100.0f);

but I get some strange problems…

not all the places are fogged correctly…
the walls/polygons/objects that are perpenticular to the X and Z axes and crossing the cameras position are not fogged!
look this screen:

http://bekengine.periergoi.gr/Screenshots/probfog1.JPG

what is going on? :cry:

thank you!

It looks like typical GL_PROJECTION vs. GL_MODELVIEW problem, as if you used glRotate 90° in GL_PROJECTION matrix mode.
See
http://opengl.org/resources/faq/technical/viewing.htm#view0030

hhmm…
I dont think that is something wrong with it… here is how i setup the camera:

glMatrixMode(GL_PROJECTION);
glLoadMatrixf(ProjectionMatrix);
glMatrixMode(GL_MODELVIEW);
ModelViewMatrix.Rotate(-rx,-ry,-rz);
ModelViewMatrix.Translate(-Pos);
glLoadMatrixf(ModelViewMatrix);

:confused:

You can’t use OpenGL built in fog if you are using Fragment Program (or need to use the option ‘fog’).

You can still code it in your fragment program.

In ARB fragment:
LRP_SAT result.color, fragment.fogcoord.x, state.fog.color, r0;

in GLSL (very caution, on ATI 9x00 series, it’s software emulated).
gl_FragColor = mix(gl_Fog.color, r0, gl_FogFragCoord);

in each formula, r0 is the final pixel shader color.

Else, does your fog is set up correctly ? (ie works without VS and PS ?)

hhhmm… without the pixel/vertex shaders the fog is correct… :mad: :mad: :mad:

maybe is something wrong with the vertex/pixel shader? here is the vertex shader:
http://rafb.net/paste/results/EFvc4m28.html

and here is the pixel shader:
http://rafb.net/paste/results/Bgq9sp22.html

:confused:

Hmmmm. I just set up fog according to your code and used your shaders. Fog on my unshaderized surfaces is fine, but I don’t see any fog at all where the shader is applied. Using a GeForce 6800GT on Linux.

You need to write to result.fogcoord in your vertex program.

Here’s the GLSL code to calculate your fog coordinate:

vec4 eyePos = gl_ModelViewMatrix * gl_Vertex;
gl_FogFragCoord = abs(eyePos.z/eyePos.w);

and here’s the equivalent ARB_vertex_program code:

PARAM modelview = { state.matrix.modelview };
DP4 R0.x, vertex.position, modelview[2];
DP4 R0.y, vertex.position, modelview[3];
RCP R0.y, R0.y;
MUL R0.x, R0, R0.y;
ABS result.fogcoord.x, R0;

you are right man! Thanks for your help!