20

我正在开发一个显示一些 3D 模型的应用程序。我们加载模型,创建网格,将它们添加到场景中……标准程序。添加最后一个网格后,我们计算边界框以移动相机并覆盖所有场景,使用总几何体的大小和视口的大小进行数学运算。

    if (bounds.bx / bounds.by < camera.aspect) {
        /* Vertical max */
        r = bounds.by / (2 * Math.tan(Math.PI / 8));
    } else {
        /* Horizontal max */
        hFOV = 2 * Math.atan(Math.tan(Math.PI / 8) * camera.aspect);
        r = bounds.bx / (2 * Math.tan((hFOV / 2)));
    }

bounds是一个包含边界框宽度和高度的对象。在这个计算之后,我们移动相机(加上一点比例,只是美学,我们希望几何体和屏幕边框之间有一点空间:))并渲染

    camera.position.z = r * 1.05;

到目前为止,这已实现并且运行正常。这是使用 PerspectiveCamera 完成的。现在我们想改变它并使用 OrthographicCamera……结果是一团糟。模型太小,我们失去了轨迹球控件的鼠标滚轮缩放,移动相机的算法不再起作用。另外我不明白相机构造函数的参数......这些宽度和高度是用于几何图形还是视口?

4

3 回答 3

44

在 three.js 中实例化正交相机的模式是:

var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, near, far );

其中width和是以世界空间单位height测量的相机长方体截头体的宽度和高度。

nearfar是到视锥体的近平面和远平面的世界空间距离。两者都near应该far大于零。

为防止失真,您通常希望正交相机 ( width / height) 的纵横比与渲染画布的纵横比相匹配。(见下文*注)

不幸的是,许多 three.js 示例都通过window.innerWidthwindow.innerHeight作为参数传递给了这个构造函数。仅当正交相机用于渲染纹理,或者正交场景的世界单位以像素为单位时,这样做才有意义。


*注意:实际上,相机纵横比应该与渲染器视口的纵横比相匹配。视口可以是画布的子区域。如果您不直接使用 设置渲染器的视口renderer.setViewport(),则视口将与画布大小相同,因此与画布具有相同的纵横比。

三.js r.73

于 2013-07-10T09:39:08.403 回答
10

供将来参考: 更新的视频

var w = container.clientWidth;
var h = container.clientHeight;
var viewSize = h;
var aspectRatio = w / h;

_viewport = {
    viewSize: viewSize,
    aspectRatio: aspectRatio,
    left: (-aspectRatio * viewSize) / 2,
    right: (aspectRatio * viewSize) / 2,
    top: viewSize / 2,
    bottom: -viewSize / 2,
    near: -100,
    far: 100
}

_camera = new THREE.OrthographicCamera ( 
    _viewport.left, 
    _viewport.right, 
    _viewport.top, 
    _viewport.bottom, 
    _viewport.near, 
    _viewport.far 
);

在我的具体情况下,我的世界单位是像素。因此,我使用container.clientWidthandcontainer.clientHeight作为宽度和高度。你可能不想这样做。

于 2015-02-05T14:24:41.710 回答
-3
            camera.top = (.95*camera.top);
            camera.bottom = (.95*camera.bottom);
            camera.left = (.95*camera.left);
            camera.right = (.95*camera.right);
于 2014-01-20T05:51:39.097 回答