three.js基础 - PerspectiveCamer

基本概念

cone:锥体。

frustum: 截头锥体。也就是截掉头部的截体。如下图:

field of view(FOV): 视野,表示可视范围 。常用角度来表示。

Viewing frustum: 视锥体。视锥体只是截头锥体在透视相机系统中的具体表达。three.js中的视锥体又特指底面为四边形的截头锥体。锥体顶点被视作相机位置。如下图所示:

使用方法

在three.js中,构建函数THREE.PerspectiveCamera,就是用来定义透视投影相机(Perspective Camera)的视锥体的。视锥体是空间物体的容器,物体位于视锥体内的部分才可能会显示出来,位于视锥体外的部分则会被剪切掉。

PerspectiveCamera的用法如下:

const camera = THREE.PerspectiveCamera(fov, aspect, near, far)
  • fov 垂直方向(y轴方向)的可视角度 
  • aspect 实际窗口的纵横比,为保证物体不出现比例上的变形,一般设置为容器的width/height
  • near 相机与近平面的距离
  • far 相机与远平面的距离

只有这几个参数的话,PerspectiveCamera就只是定义了一个形状。只有形状,没有位置,又怎么能知道某个物体是否在这个形状内呢?

其实,在three.js的坐标系(也称全球坐标系)中,所有三维物体,包括上面定义的camera,都被设置了一个默认位置的:(0, 0, 0),即原点。全球坐标系示意如下图:

视锥体在坐标系中的位置,示意如下:

如果不改变各个物体的默认位置,camera就会位于物体的内部,其定义的视锥体如果也正好在物体的外面的话,那就不会有任何的投影,屏幕会是一片空白。

所以,为了完整地投影三维物体,我们可以通过调整camera的位置或者视锥体的参数(fov/aspect/near/far),来确保三维物体位于视锥体的内部。

代码示例

下面举例说明。

最好结合这个完整示例代码来看。

首先,定义一个位于原点,尺寸为(1,1,1)的立方体。

const scene = new THREE.Scene();
const geometry = new THREE.BoxGeometry(1, 1, 1);
const material = new THREE.MeshBasicMaterial({ color: 0x00ff00, wireframe: true });
const cube = new THREE.Mesh(geometry, material);
scene.add(cube);

定义一个z轴位于5的相机(立方体的z轴最大值为0.5)

const camera = new THREE.PerspectiveCamera(
  60,
  window.innerWidth / window.innerHeight,
  0.1,
  10
);
camera.position.set(0, 0, 5);

可以看到立方体完整投影,效果如下图。其中小正方形为立方体背面投影,大正方形为正面投影。近大远小。

调整相机位置,将其移到立方体后方

camera.position.set(0, 0, -0.5)

屏幕为空。

再调整相机方位置,让其只能看到立方体的背面,但看不到前方

camera.position.set(0, 0, 0.4);

效果如下图:

总结

PerspectiveCamer定义了被称为视锥体的三维虚拟容器,位于其内部的物体会保留,位于外部的被剪切掉。留下的部分,和坐标系一起投影到二维平面如浏览器canvas中,就是我们看到的最终效果。

参考资料

你可能感兴趣的:(three.js前端)