Take the 2-minute tour ×
Game Development Stack Exchange is a question and answer site for professional and independent game developers. It's 100% free, no registration required.

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

share|improve this question
add comment

2 Answers

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

share|improve this answer
add comment
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];
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!

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
add comment

Your Answer

 
discard

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.