Calculate near/far plane vertices using THREE.Frustum
javascript, opengl-es, three.js, webgl
Solution
`Three.Frustum` is not really going to help you -- it is a set of planes. The good news is your solution appears correct, but there is an easier way to think about this.
The upper right corner of the near plane is a point in camera space with these coordinates:
var ntr = new THREE.Vector3( wNear / 2, hNear / 2, -camera.near );
using your definition of `wNear` and `hNear`, which are correct.
Now, making sure that `camera.matrixWorld` is updated, you convert that point to world coordinates like so:
camera.updateMatrixWorld();
ntr.applyMatrix4( camera.matrixWorld );
Now, flip the signs to get the other three corners, and then repeat the calculation for the far plane.
See, you had it right; you just took a more complicated route. :-)
EDIT: updated to three.js r.66
Problem
I need some help to deal with THREE.Frustum object. My problem: I need to calculate near/far plane vertices; I've taken a look at these tutorials - http://www.lighthouse3d.com/tutorials/view-frustum-culling/view-frustums-shape/ - http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-extracting-the-planes/ and I've sketched this function implementing exactly (I hope so) the procedure explained (just to get top-left/right vertices, assuming the camera can only look left and right): ``` // Near Plane dimensions hNear = 2 * Math.tan(camera.fov / 2) * camera.near; // height wNear = hNear * camera.aspect; // width // Far Plane dimensions hFar = 2 * Math.tan(camera.fov / 2) * camera.far; // height wFar = hFar * camera.aspect; // width getVertices : function() { var p = camera.position.clone(); var l = getCurrentTarget(); // see below var u = new THREE.Vector3(0, 1, 0); var d = new THREE.Vector3(); d.sub(l, p); d.normalize(); var r = new THREE.Vector3(); r.cross(u, d); r.normalize(); // Near Plane center var dTmp = d.clone(); var nc = new THREE.Vector3(); nc.add(p, dTmp.multiplyScalar(camera.near)); // Near Plane top-right and top-left vertices var uTmp = u.clone(); var rTmp = r.clone(); var ntr = new THREE.Vector3(); ntr.add(nc, uTmp.multiplyScalar(hNear / 2)); ntr.subSelf(rTmp.multiplyScalar(wNear / 2)); uTmp.copy(u); rTmp.copy(r); var ntl = new THREE.Vector3(); ntl.add(nc, uTmp.multiplyScalar(hNear / 2)); ntl.addSelf(rTmp.multiplyScalar(wNear / 2)); // Far Plane center dTmp.copy(d); var fc = new THREE.Vector3(); fc.add(p, dTmp.multiplyScalar(camera.far)); // Far Plane top-right and top-left vertices uTmp.copy(u); rTmp.copy(r); var ftr = new THREE.Vector3(); ftr.add(fc, uTmp.multiplyScalar(hFar / 2)); ftr.subSelf(rTmp.multiplyScalar(wFar / 2)); uTmp.copy(u); rTmp.copy(r); var ftl = new THREE.Vector3(); ftl.add(fc, uTmp.multiplyScalar(hFar / 2)); ftl.addSelf(rTmp.multiplyScalar(wFar / 2)); getCurrentTarget : function() { var l = new THREE.Vector3(0, 0, -100); this.camera.updateMatrixWorld(); this.camera.matrixWorld.multiplyVector3(l); return l; } ``` This seems to work but... My Question: Can I obtain the same result in a more elegant (maybe more correct) way, using a THREE.Frustum object?