我正在开发一个可以显示一些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是包含边框的宽度和高度的对象。经过此计算,我们移动了相机(加上一点点比例,只是为了美观,我们希望在几何体和屏幕边框之间留出一点空间:))并进行渲染
bounds
camera.position.z = r * 1.05;
到目前为止,这已实现并且可以正常运行。这是通过PerspectiveCamera完成的。现在我们要更改它并使用OrthographicCamera …结果是一团糟。模型太小,我们无法从TrackBall控件获得鼠标滚轮缩放,并且移动摄像机的算法不再起作用。我也不了解相机的构造函数的参数…这些宽度和高度是用于几何图形还是用于视口?
在three.js中实例化正交摄影机的模式是:
var camera = new THREE.OrthographicCamera( width / - 2, width / 2, height / 2, height / - 2, near, far );
其中width和height是以 世界空间 单位测量的相机的长方体平截头体的宽度和高度。
width
height
near并且far是 世界空间 距离平截面近及远的飞机。双方near并far应大于零。
near
far
为防止失真,通常需要使正交摄影机(width / height)的纵横比与渲染画布的纵横比匹配。(请参阅下面的*注)
width / height
不幸的是,许多例子通过three.js所的window.innerWidth,并window.innerHeight作为参数传递给这个构造函数。仅在使用正交摄影机渲染纹理时,或者正交摄影场的世界单位为像素时,才有意义。
window.innerWidth
window.innerHeight
*注意:实际上,相机的纵横比应与渲染器视口的纵横比匹配。视口可以是画布的子区域。如果不使用直接设置渲染器的视口renderer.setViewport(),则视口将与画布相同,因此具有与画布相同的纵横比。
renderer.setViewport()
three.js r.73