Game Development Stack Exchange is a question and answer site for professional and independent game developers. Join them; it only takes a minute:

Sign up
Here's how it works:
  1. Anybody can ask a question
  2. Anybody can answer
  3. The best answers are voted up and rise to the top

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.w;

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

enter image description here

share|improve this question
up vote 4 down vote accepted

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];
float heightOfNearPlane = (float)abs(viewport[3]-viewport[1]) /

Which you pass in as a uniform.

Thx to the coders on ##opengl that helped me sort this out!

share|improve this answer
Don't forget to call glEnable(GL_VERTEX_PROGRAM_POINT_SIZE)to allow setting of point size from vertex shader. – Christoph Halang Dec 17 '13 at 11:28

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;
  //  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));

Here is my talk on jMonkey engine:

share|improve this answer

Your Answer


By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.