使用THREE.Frustum计算近/远平面顶点

时间:2012-08-18 12:49:08

标签: javascript opengl-es webgl three.js

我需要一些帮助来处理THREE.Frustum对象。

我的问题:

我需要计算近/远平面顶点;我看过这些教程

  1. http://www.lighthouse3d.com/tutorials/view-frustum-culling/view-frustums-shape/
  2. http://www.lighthouse3d.com/tutorials/view-frustum-culling/geometric-approach-extracting-the-planes/
  3. 我已经勾勒出这个函数完全实现(我希望如此)所解释的过程(只是为了得到左上/右上顶点,假设相机只能向左和向右看):

            // 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;
        }
    

    这似乎有效但......

    我的问题:

    我可以使用THREE.Frustum对象以更优雅(可能更正确)的方式获得相同的结果吗?

1 个答案:

答案 0 :(得分:7)

Three.Frustum并没有真正帮助你 - 它是一组飞机。好消息是你的解决方案看似正确,但有一种更简单的方法可以考虑这一点。

近平面的右上角是相机空间中具有以下坐标的点:

var ntr = new THREE.Vector3( wNear / 2, hNear / 2, -camera.near );

使用您对wNearhNear的定义,这是正确的。

现在,确保camera.matrixWorld已更新,您将该点转换为世界坐标,如下所示:

camera.updateMatrixWorld();
ntr.applyMatrix4( camera.matrixWorld );

现在,翻转标志以获得其他三个角,然后重复远平面的计算。

看,你做对了;你刚刚走了一条更复杂的路线。 : - )

编辑:更新为three.js r.66