PDA

View Full Version : per pixel fog

vince
06-14-2006, 09:39 PM
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

zed
06-14-2006, 10:20 PM
I could also compute it based on gl_FragCoord.z, but this wouldn't give me radial fog. i think it would

vince
06-14-2006, 11:36 PM
Why would it? The z buffer only record the z component. A R-buffer would do it radialy, but not a z component.

foobar
06-15-2006, 04:35 AM
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.

vince
06-15-2006, 09:43 AM
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?

Flavious
06-15-2006, 12:45 PM
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.

Humus
06-15-2006, 01:37 PM
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);
...
...
}

vince
06-15-2006, 03:29 PM
Originally posted by Humus:
Something like this should work:
I knew there was an obvious solution! Thanks Humus :)

zed
06-15-2006, 10:01 PM
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

vince
06-16-2006, 09:27 AM
Originally posted by zed:
yeah sorry i was wrong No problem ;)

foobar
07-22-2006, 09:58 AM
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.