7
\$\begingroup\$

How can you scale a point sprite by its distance from the camera?

GLSL fragment shader: gl_PointSize = size / gl_Position.w; seems along the right tracks; for any given scene all sprites seem nicely scaled by distance. Is this correct?

How do you compute the proper scaling for my vertex attribute size? I want each sprite to be scaled by the modelview matrix.

I had played with arbitrary values and it seems that size is the radius in pixels at the camera, and is not in modelview scale.

I've also tried:

gl_Position = pMatrix * mvMatrix * vec4(vertex,1.0);
vec4 v2 = pMatrix * mvMatrix * vec4(vertex.x,vertex.y+0.5*size,vertex.z,1.0);
gl_PointSize = length(gl_Position.xyz-v2.xyz) * gl_Position.w;

But this makes the sprites be bigger in the distance, rather than smaller:

enter image description here

\$\endgroup\$

2 Answers 2

8
\$\begingroup\$

To answer my own question, here's what I got working:

The scaling in the GLSL vertex shader is:

gl_PointSize = (heightOfNearPlane * pointSize) / gl_Position.w;

Where you compute your heightOfNearPlane using the viewport height and the field-of-view angle you constructed the perspective matrix with:

float fovy = 60; // degrees
int viewport[4];
glGetIntegerv(GL_VIEWPORT,viewport);
float heightOfNearPlane = (float)abs(viewport[3]-viewport[1]) /
    (2*tan(0.5*fovy*PI/180.0));

Which you pass in as a uniform.

Thx to the coders on irc.freenode.net ##opengl that helped me sort this out!

\$\endgroup\$
1
  • 5
    \$\begingroup\$ Don't forget to call glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)to allow setting of point size from vertex shader. \$\endgroup\$ Dec 17, 2013 at 11:28
1
\$\begingroup\$

I found the solution to scale PointSprites:

const float SIZE_MULTIPLIER = 300.0;
 attribute float inSize;
uniform vec2 g_Resolution;
…

vec4 modelSpacePos = vec4(inPosition, 1.0);
vec4 position = g_WorldViewProjectionMatrix * modelSpacePos;
#ifdef POINT_SPRITE
  //  vec4 worldPos = modelSpacePos  * modelSpacePos;
    float spriteDist;

    if (position.w == 0.0) {
      spriteDist = 0.00001;
    } else {
      spriteDist = position.w;
    }

    gl_PointSize = (((inSize * SIZE_MULTIPLIER * (g_Resolution.x/g_Resolution.y)) / spriteDist) * (g_Resolution.x/g_Resolution.y));
#endif

Here is my talk on jMonkey engine: http://hub.jmonkeyengine.org/forum/topic/pointsprote-size-limitation/#post-250817

\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .