问题
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;
回答1:
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.
来源:https://stackoverflow.com/questions/20351466/gl-pointsize-to-screen-coordinates