arb_vertex_program and fog

Hi,

I have some meshes running trough a vertex program and all is fine, but, when i enable fog, everything gets messed up.
So, when the fog is enabled, the mesh becomes in full fog, if the fog color is blue, the mesh is 100% blue.

So, i did this in the vertex program :

"ATTRIB fogP = vertex.attrib[5];
""MOV result.fogcoord, fogP;
"
But, now the mesh seems looks like there’s no fog enabled, it seems the fog density or something like that is missing in the vp.

Anyone knows how to fix this ?
thanks,

Bruno

The fog coord is in rage [0,1], not world or eye units.

so ?

Are you setting vertex.attrib[5] in your app or are you expecting attribute 5 to alias with the conventional FogCoord attribute (this is only aliased on NVIDIA GPUs on the PC)?

Originally posted by jwatte:
The fog coord is in rage [0,1], not world or eye units.
Is this correct? In the OpenGL spec, equations 3.30, 3.31, and 3.32 seem to indicate that the fog coordinate doesn’t have a range limit. The fog factor, or the result of the function of the fog coordinate, does get clamped to [0,1], however.

Bruno, what are you setting VertexAttrib(5) to? What kind of fog are you using (linear, exponential, fragment program)?

I’m using standard exponential fog (GL_EXP).

I’m not setting VertexAttrib(5) to anything.,
From what i understand several opengl attributes are stored in the registry, isn’t this correct ?
Attrib(5) for fog, Attrib(8) for texture coordinates, etc.
Do i need to make some special assign, regarding fog ?

thanks

You either need to calculate the fog coordinate yourself in the vertex program, or you need to set it per vertex using glFogCoord.

Here is some example code for calculating the fog coordinate in a GLSL vertex shader:

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

The attrib(5) is only for ‘per vertex’ fog coordinates, it means, fog coordinates that is specificied in your model.

Now, if you are using fog with vertex program you MUST write a fragment program to blend the fog color with the final color of the your program.

It’s your responsability to compute the fog coordinate (see previous post for example) and , unlike DirectX, blend that value with the current fog color;

This also means that doing fog with vertex program on hardware that doesn’t have ARB fragment program is not possible (*)

Same as If you using GLSL: You need to ‘mix’ the result : gl_FragColor = mix(gl_Fog.color, r0, gl_FogFragCoord);

Also remember that when fog enabled, GLSL is software emulated on ATI video cards.

(*) At least not possible on ATI video cards;

Originally posted by execom_rt:
[b]…

Now, if you are using fog with vertex program you MUST write a fragment program to blend the fog color with the final color of the your program.

It’s your responsability to compute the fog coordinate (see previous post for example) and, unlike DirectX, blend that value with the current fog color;

This also means that doing fog with vertex program on hardware that doesn’t have ARB fragment program is not possible (*)

(*) At least not possible on ATI video cards;[/b]
I don’t think this is correct. You can definitely use vertex programs with fixed-function fog as long as you write a valid value to the vertex program result “fogcoord”. Typically this is something like the z-coordinate of your vertex in eye-space, though what you write to “fogcoord” really depends on the values of your fog parameters and the types of transformations you do in your vertex program.

It is correct that with fragment programs enabled you must “blend the fog color with the final color” you calculate in your program… unless you use one of the fixed-function fog fragment program OPTIONs. If you do use one of the fixed-function fog fragment program options your fragments should be correctly fogged even if you’re using fragment programs.

Bruno, are you doing a “traditional” transformation in your vertex program, i.e. using the position invariant vertex program option or multiplying by the MVP matrix? If so, adding this to your vertex program ought to do the trick:

DP4 result.fogcoord.x, vertex.position, state.matrix.modelview.row[2];

Many thanks secnuop , that did the trick :slight_smile:

Just one thing scared me, the first time i run it to check if it would work, the mesh was rendered like if it had missing faces, and i got a ATI recovery window thing , however just happened the first time it run, i run it several times after it, and it run just fine :slight_smile:

thanks again everyone,

Bruno

Originally posted by execom_rt:
Now, if you are using fog with vertex program you MUST write a fragment program to blend the fog color with the final color of the your program.

A fragment program is not required when using fog with a vertex program. The fixed function fragment pipeline will apply fog using the fog coordinate you output from your vertex program.

Yes that’s the theory, but i’ve just retested a sample code (ATI 9800 Pro, Catalyst 4.10).

  • Using GLSL: Unable to test, it runs at 0 fps (using sw rendering when fog is enabled)

  • Using ARB vertex program only : Fog is not performed.

  • Just adding a ARB fragment program to blend the fog with color : It works.

I will try on a GF3 tomorrow, but i predict the same result.

Now, if you are using fog with vertex program you MUST write a fragment program to blend the fog color with the final color of the your program.

So what you are trying to say is that you can’t do fog on hardware that doesn’t support fp’s if you use vp’s? So that means you won’t be able to get Fog to work on your Gf3 at all (unless you are running nvEmulate).

Originally posted by execom_rt:
[b]- Using GLSL: Unable to test, it runs at 0 fps (using sw rendering when fog is enabled)

  • Using ARB vertex program only : Fog is not performed.
    [/b]
    Sounds like a couple of driver bugs.

Here my latest tests:

ATI Radeon 9800 Pro - Catalyst 4.10

  • GLSL vertex shader (with no fragment pass) :
    Fog not performed, Software emulated

  • GLSL vertex shader + fragment pass :
    Fog performed, Software emulated

  • ARB vertex program (with no fragment pass):
    Fog not performed

  • ARB vertex program (with fragment pass):
    Fog performed

nVidia Geforce3 Ti 200 - Forceware 66.93

  • GLSL vertex shader (with no fragment pass) :
    Fog not performed

  • ARB vertex program (with no fragment pass):
    Fog not performed

nVidia Geforce4MX - MacOS X 10.3.6

  • GLSL vertex shader : Unsupported
  • ARB vertex program (with no fragment pass) : Fog not performed

Of course, I would be glad if someone can show me a working sample code with vertex program + fog without using fragment program. But AFAIK, there is nothing I could find on the web (not using ARB vertex program).

Originally posted by execom_rt:
Of course, I would be glad if someone can show me a working sample code with vertex program + fog without using fragment program. But AFAIK, there is nothing I could find on the web (not using ARB vertex program).
VP With Fog Sample App

I’ve included a VC7 solution, but it uses glut so it should be trivial to port it to just about anything else…

Here’s another example, this one uses GLSL: http://www.jcode.org/files/fog.zip

By default it only uses a vertex shader. Press ‘s’ to switch between fixed function and shaders. Press ‘f’ to switch between linear, exp, and exp2 fog.

It comes with a fragment shader that you can enable by setting the useFragmentShader boolean at the top of fog.cpp.

Ok i found the problem in my end.
Basically
I was doing this : (Radial fog)

DP3 Rh.x, v0, ModelViewMatrix[0];
DP3 Rh.y, v0, ModelViewMatrix[1];
DP3 Rh.z, v0, ModelViewMatrix[2];
DP3 Rh.w, v0, ModelViewMatrix[3];
RCP R0.w, Rh.w;
MUL Re, Rh, R0.w;
DP4 R1.z, R1.z;
RSQ R1.z, R1.z;
RCP R1.z, R1.z;

MAD R1.z, R1.z, -Fog.z, -Fog.y;
MIN R1.,R1.z, 1.0;
MAX oFog, R1.z, 0.0;

(Fog.z = 1/(end-start), Fog.y = end/Fog.z)

The 3 lines of the last part were wrong. The rescale f=(end-z)/(end-start) is done automatically, So it was rescale twiced, so displayed nothing to my case (was broken).

This is a different behaviour from DirectX, where the rescale must be performed in vertex shader.

I need just to move the 3 last bits in my fragment part.
So it’s working fine, on GF3 and ATI, even without fragment program.

For GLSL fog is still broken on ATI tough - I couldn’t recompile / test the last example from the previous post. it ended with some compilation error in the GLSL code. :rolleyes: