Thursday, April 7, 2016

glsl - scaling point sprites with distance


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



Answer



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!


No comments:

Post a Comment

Simple past, Present perfect Past perfect

Can you tell me which form of the following sentences is the correct one please? Imagine two friends discussing the gym... I was in a good s...