You just need to convert all the vertices to screen space and make them a 2D bounding box:
function computeScreenSpaceBoundingBox(mesh, camera) { var vertices = mesh.geometry.vertices; var vertex = new THREE.Vector3(); var min = new THREE.Vector3(1, 1, 1); var max = new THREE.Vector3(-1, -1, -1); for (var i = 0; i < vertices.length; i++) { var vertexWorldCoord = vertex.copy(vertices[i]).applyMatrix4(mesh.matrixWorld); var vertexScreenSpace = vertexWorldCoord.project(camera); min.min(vertexScreenSpace); max.max(vertexScreenSpace); } return new THREE.Box2(min, max); }
The resulting Box2 is in the normalized screen coordinates [-1, 1]. You can get pixels by multiplying by half the height and width of your renderer:
function normalizedToPixels(coord, renderWidthPixels, renderHeightPixels) { var halfScreen = new THREE.Vector2(renderWidthPixels/2, renderHeightPixels/2) return coord.clone().multiply(halfScreen); }
See a demo of this here: http://jsfiddle.net/holgerl/6fy9d54t/
EDIT: Reduced memory usage in the inner loop as suggested by @WestLangley
EDIT2: fixed bug detected by @manthrax
source share