繁体   English   中英

Three.js - 正交相机

[英]Three.js - Orthographic camera

我正在开发一个显示一些 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 ......结果是一团糟。 模型太小,我们失去了轨迹球控件的鼠标滚轮缩放,并且移动相机的算法不再起作用。 另外我不明白相机构造函数的参数......这些宽度和高度是用于几何图形还是视口?

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

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

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

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

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

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


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

三.js r.73

供将来参考:更新的视频

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.clientWidthcontainer.clientHeight作为宽度和高度。 你可能不想这样做。

            camera.top = (.95*camera.top);
            camera.bottom = (.95*camera.bottom);
            camera.left = (.95*camera.left);
            camera.right = (.95*camera.right);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM