per pixel fog

I’m trying to create radial per pixel fog, but I can’t find a way that works because I need the distance to fragment which I don’t have. I know I could get it from the vertex shader, but that gives me per vertex fog which is unaccurate for large polygons. I could also compute it based on gl_FragCoord.z, but this wouldn’t give me radial fog.

I’m sure there’s a way to get the accurate fragment distance to the eye, but I don’t see it. Anybody does?

Thanks

I could also compute it based on gl_FragCoord.z, but this wouldn’t give me radial fog.
i think it would

Why would it? The z buffer only record the z component. A R-buffer would do it radialy, but not a z component.

Create a (varying) attribute which stores the eye-space position for each vertex, this gets linearly interpolated giving you the eye-space position for each fragment. Radial distance from the eye is then the magnitude of this vector.

Originally posted by foobar:
Create a (varying) attribute which stores the eye-space position for each vertex, this gets linearly interpolated giving you the eye-space position for each fragment. Radial distance from the eye is then the magnitude of this vector.
This is per vertex fog. I need per pixel fog. I did it, but it is unrealistic when I have large polygons. It really shows if I have large and small polygons at the same time.

Anything else?

I’m sure there’s a way to get the accurate fragment distance to the eye, but I don’t see it.
Use a per-fragment worldspace/eyespace position to calculate the distance to the eye. Or use an eyespace vertex position to tap a volume map or some clever combination of 1D/2D maps.

You can’t linearly interpolate distance. Consider a right triangle at the origin with legs 1 and 1. A linear combination of these leg lengths measured from the origin will always produce 1, which is incorrect (mid way is sqrt(2)/2). You can interpolate directions and positions, but not magnitudes (you introduce a spacial ambiguity in doing so).

The per-vertex distance technique works really well if the triangles are relatively small and/or far away.

Something like this should work:

uniform vec3 camPos;
varying vec3 pos;

void main(){
    gl_Position = ftransform();
    pos = gl_Vertex - camPos;
}
varying vec3 pos;

void main(){
    float dist = length(pos);
    ...
    ...
}

Originally posted by Humus:
Something like this should work:

I knew there was an obvious solution! Thanks Humus :slight_smile:

Originally posted by vince:
Why would it? The z buffer only record the z component. A R-buffer would do it radialy, but not a z component.
yeah sorry i was wrong

Originally posted by zed:
yeah sorry i was wrong
No problem :wink:

Create a (varying) attribute which stores the eye-space position for each vertex, this gets linearly interpolated giving you the eye-space position for each fragment. Radial distance from the eye is then the magnitude of this vector.
Keep reading this until you realise it is correct.

This topic was automatically closed 183 days after the last reply. New replies are no longer allowed.