4

When I calculate the gl_PointSize the same way I do it in the vertex shader I get a value "in pixels" (according to http://www.opengl.org/sdk/docs/manglsl/xhtml/gl_PointSize.xml). Yet this value doesn't match the measured width and height of the point on the screen. The difference between the calculated and measured size is no constant it seems.

Calculated values range from 1 (very far away) to 4 (very near)

Current code (with three.js, but nothing magic), trying to calculate the size of a point on screen:

var projector = new THREE.Projector();

var width = window.innerWidth, height = window.innerHeight;
var widthHalf = width / 2, heightHalf = height / 2;

var vector = new THREE.Vector3();
var projector = new THREE.Projector();
var matrixWorld = new THREE.Matrix4();

matrixWorld.setPosition(focusedArtCluster.object3D.localToWorld(position));

var modelViewMatrix = camera.matrixWorldInverse.clone().multiply( matrixWorld );

var mvPosition = (new THREE.Vector4( position.x, position.y,  position.z, 1.0 )).applyMatrix4(modelViewMatrix);

var gl_PointSize = zoomLevels.options.zoom * ( 180.0 / Math.sqrt( mvPosition.x * mvPosition.x + mvPosition.y * mvPosition.y + mvPosition.z * mvPosition.z ) );
projector.projectVector( vector.getPositionFromMatrix( matrixWorld ), camera );

vector.x = ( vector.x * widthHalf ) + widthHalf;
vector.y = - ( vector.y * heightHalf ) + heightHalf;

console.log(vector.x, vector.y, gl_PointSize);

Let me clarify: The goal is to get the screen size of a point, in pixels.

My vertex shader:

vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );

gl_PointSize = zoom * ( 180.0 / length( mvPosition.xyz ) );

gl_Position = projectionMatrix * mvPosition;
Doidel
  • 1,743
  • 1
  • 14
  • 22
  • Okay, so since there a zillion variables here I really have no idea what value you are trying to assign to `gl_PointSize`. Can you give me some clue as to the range of values you would compute with this code? Keeping in mind that OpenGL implementations are only required to support a range of **1.0** - **1.0** (yeah, that is not a joke, sadly). You can query your implementation's supported range by calling `glGetIntegerv (GL_POINT_SIZE_RANGE, ...)`, of course I could not begin to tell you how to do that in Three.js. A good rule of thumb is that since NV and AMD cards only support up to 64... – Andon M. Coleman Dec 04 '13 at 02:47
  • you probably should not expect an embedded implementation to support anything greater than 64 either =P Usually you would query the value rather than going by such a silly rule of thumb, but I don't know how to get that information from Three.js. – Andon M. Coleman Dec 04 '13 at 02:48
  • nm, I see you already did this. I thought those numbers in your question text were measured sizes, but those are the actual computed sizes. Still, I would consider looking into your implementation's limit to the maximum point size. It could be clamping your range to 1.0. – Andon M. Coleman Dec 04 '13 at 02:52
  • Thanks for helping. http://webglreport.com/ "Aliased Point Size Range: [1, 256]". The clamping is not the problem though. The problem is that I never receive the acual screen size of a point. The points are not 1 to 3px in size, but rather 10 to 60px. So now I'm unsure how to calculate the actual screen size. – Doidel Dec 04 '13 at 08:50
  • The factor between screen size and calculated size is **69** for calculated size 4 with measured size 276 and **12** for calculated size 1.386 with measured size 17 – Doidel Dec 04 '13 at 09:09
  • I just figured out that gl_PointSize is actually the exact screen dimension.. sooo something about my PointSize calculation must be wrong.. – Doidel Dec 04 '13 at 11:53
  • Ok either _length( mvPosition.xyz )_ is not the same as _Math.sqrt( mvPosition.x * mvPosition.x + mvPosition.y * mvPosition.y + mvPosition.z * mvPosition.z )_ or my mvPosition is calculated wrongly – Doidel Dec 04 '13 at 12:17
  • Oooh I guess the issue is because of opengl being column-major... – Doidel Dec 04 '13 at 13:00

1 Answers1

0

Since in GLSL matrices are column-major and in three.js row-major I needed to transpose the matrices in order to have the correct matrix multiplications:

var modelViewMatrix = camera.matrixWorldInverse.clone().transpose().multiply( matrixWorld).transpose();

Further there's awlays an offset of 20px to the actual screen position. I haven't figured out why yet, but I had to do:

vector.x = ( vector.x * widthHalf ) + widthHalf - 20;
vector.y = - ( vector.y * heightHalf ) + heightHalf - 20;

Thirdly we'll have to take browser zoom into account. For width and height we probably have to somehow work with renderer.devicePixelRatio. I hope to figure out how soon enough, and I'll post it here.

Thanks for the help nonetheless. Glad it's solved.

Doidel
  • 1,743
  • 1
  • 14
  • 22