implementing simple fog in a fragment program

Hi all,
I’m trying to implement simple exponential fogging via a fragment/vertex program pair. The setup works fine when using the fixed pipeline but once vertex and fragment programs are enalbed I get fogging allright but with a weird discontinuity. By discontinuity I mean that my terrain fades as it should to fog color as the eye depth increases but at some depth it gets abruptly completely foggy and of course remains that way.

I’m not sure what I’m doing wrong but info on fragment programs is pretty scarce on the net. I’m postin the vertex/fragment program pair in case someone can give me a clue as to what the problem might be.

static char vertex[] =
"!!ARBvp1.0                                             
\
## Standard transform                                   
\
DP4 result.position.x, state.matrix.mvp.row[0], vertex.position;           
\
DP4 result.position.y, state.matrix.mvp.row[1], vertex.position;           
\
DP4 result.position.z, state.matrix.mvp.row[2], vertex.position;           
\
DP4 result.position.w, state.matrix.mvp.row[3], vertex.position;           
\
DP4 result.fogcoord.x, state.matrix.modelview.row[2], vertex.position; 
\
DP4 result.texcoord.x, vertex.position, state.texgen[0].object.s; 
\
DP4 result.texcoord.y, vertex.position, state.texgen[0].object.t; 
\
END
";

static char fragment[] =
"!!ARBfp1.0
"
"TEMP d;
"
"PARAM b = {0, 0, 0, 1};
"
"PARAM w = {1, 1, 1, 1};
"
"ATTRIB f = fragment.fogcoord;
"

"MUL d.x, 0.00005, f.x;
"
"EX2_SAT d.x, d.x;
"
"MOV result.color, d.x;
"
"END";
 

PS: I’ve seen some snipplets on the net where the absolute value of the eye z was taken. I can’t figure out why that’d be necessary (all visible fragments should have the same sign on their eye z, shouldn’t they) but I’ve tried it with no success.

PS2: I know that I don’t actually use the fog factor to blend in the code above. But then again it is this factor that I get wrong so that has nothing to do with my problem.

You probably want to change your EX2 to:

EX2_SAT d.x, -d.x;

You should be aware that on Nvidia hardware, it’s faster to use OPTION ARB_fog_exp because there is dedicated fog silicon – the precision is lower, though.

You probably want to change your EX2 to:

EX2_SAT d.x, -d.x;

I have tried that but d.x seems to be negative allready. Using -d.x I get no fog at all. Isn’t this normal? I mean if the opengl coordinate system has the z axis pointing out of the screen then pixels in front of the eye should have negative depths, shouldn’t they?

You should be aware that on Nvidia hardware, it’s faster to use OPTION ARB_fog_exp because there is dedicated fog silicon – the precision is lower, though.
Well I don’t intend to do fogging just the way fixed function GL does it so I don’t think I can use the option.

I have also tried diasbling the vertex program and I get the exact same result so the problem seems to be with the fragment program.

It turns out it was a matter of precision as I had suspected. Although it is kind of weird: Multiplying the eye depth by the density in the vertex program before passing it to the fragment program seems to work. So I suppose it is during the interpolation stage that precision is lost.

On some hardware (older stuff. I haven’t heard of it on anything recent), precision in interpolation is lost when passing values via a color (rather than a texture coordinate). And, if I recall correctly, fragment.fogcoord is usually the alpha of the secondary color for the fixed-function pipeline.