I'm trying to emulate distance attenuation in OpenGL ES 2.0 for GL_POINTS. So far, I have gotten to section 3.3 of this document on the OpenGL ES 1.1 implementation:
http://www.khronos.org/registry/gles/specs/1.1/es_full_spec_1.1.12.pdf
It says that attenuation is does by clamping the attenuation factor by the implementation's clamp and the user's clamp. Also, distance is the distance the point is from the camera. I have that setup, but I'm not completely sure how to find what a, b, and c represent. I was told they are attenuation factors, which makes sense, then I was also told that a = 1.0f, b = 0.0f, and c = 0.0f which would make the bottom part of the attenuation factor zero by default. This is not correct.
Does anyone have any advise on how to emulate this? Screen-aligned points are not helping me when my particle emitters are being transformed in 3D perspective.
GL_POINTS Distance Attenuation
Started by Vincent_M, Jun 21 2010 06:29 AM
3 replies to this topic
Sponsor:
#2 Members - Reputation: 291
Posted 22 June 2010 - 10:18 AM
im looking at the spec for ARB_point_parameters
OK d == distance
u can supply a,b+c quadratic equation
try some numbers
a=1,b=0,c=0
1 / ( 1 + 0 * d + 0 * d^2 ) == 1, i.e. point size will never change no matter how far away it is
a=1,b=1,c=0, d=1
1 / ( 1 + 1 * 1 + 0 * 1^2 ) = 0.5 @ 1 unit distance point is half size
a=1,b=1,c=0, d=10
1 / ( 1 + 1 * 10 + 0 * 10^2 ) = 0.09 @ 10 units distance point is smaller than a tenth
i.e. by changing a,b,c, u can control how quickly the point will shrink
1
dist_atten(d) = -------------------
a + b * d + c * d^2
OK d == distance
u can supply a,b+c quadratic equation
try some numbers
a=1,b=0,c=0
1 / ( 1 + 0 * d + 0 * d^2 ) == 1, i.e. point size will never change no matter how far away it is
a=1,b=1,c=0, d=1
1 / ( 1 + 1 * 1 + 0 * 1^2 ) = 0.5 @ 1 unit distance point is half size
a=1,b=1,c=0, d=10
1 / ( 1 + 1 * 10 + 0 * 10^2 ) = 0.09 @ 10 units distance point is smaller than a tenth
i.e. by changing a,b,c, u can control how quickly the point will shrink
#3 Members - Reputation: 3827
Posted 22 June 2010 - 10:41 AM
I think the OP means a linear distance attenuation, so decoding the equation for point attenuation we get a being a constant factor (irrespective of distance), b being a linear factor and c being an exponential factor. So if it's linear attenuation you want you should set a and c to 0 and b to non-0 (>= 1).
Bear in mind that there is a maximum point-size you can use, so up really close your points will be clamped to this size. If that's not what you want you'll probably need to use billboards instead.
Bear in mind that there is a maximum point-size you can use, so up really close your points will be clamped to this size. If that's not what you want you'll probably need to use billboards instead.
#4 Members - Reputation: 105
Posted 16 September 2012 - 02:20 PM
Another way to do this is just use normalized device coordinates,
// vertex shader:
gl_Position = modelViewProjectionMatrix * position ;
vec3 ndc = gl_Position.xyz / gl_Position.w ; // perspective divide.
float zDist = 1.0-ndc.z ; // 1 is close (right up in your face,)
// 0 is far (at the far plane)
gl_PointSize = 50.0*zDist ; // between 0 and 50 now.
psColor = vec4( color, 1 ) ;
psColor.xyz = vec3( zDist, zDist, zDist ) ;

I'm not sure this is exactly what point distance attenuation did in 1.0, but it works pretty well
// vertex shader:
gl_Position = modelViewProjectionMatrix * position ;
vec3 ndc = gl_Position.xyz / gl_Position.w ; // perspective divide.
float zDist = 1.0-ndc.z ; // 1 is close (right up in your face,)
// 0 is far (at the far plane)
gl_PointSize = 50.0*zDist ; // between 0 and 50 now.
psColor = vec4( color, 1 ) ;
psColor.xyz = vec3( zDist, zDist, zDist ) ;

I'm not sure this is exactly what point distance attenuation did in 1.0, but it works pretty well






