目录
本篇文章基于games202作业0的框架结构,对three.js程序结构中的——相机基本操作进行学习,过程中会举例作业结构。
1 确定投影方式
参考:PerspectiveCamera – three.js docs (webgl3d.cn)
针对投影方式的不同,相机分为:
- 透视投影照相机 THREE.PerspectiveCamera
- 正交投影照相机 THREE.OrthographicCamera
两种照相机中透视相机用的相对多一点,以作业0中代码为例:
const camera = new THREE.PerspectiveCamera(75, gl.canvas.clientWidth / gl.canvas.clientHeight, 0.1, 1000);
//透视照相机
.PerspectiveCamera(fov:Float, aspect:Float, near:Float, far:Float);
()里的参数分别表示:视角度数fov,相机宽高比aspect,最近距离near,最远可视距离far。是不是很熟悉?101就涉及到啦!OpenGL里就是用这四个参数"eye_fovy, aspect_ratio, zNear, zFar"来定义一个view frustum,即视锥体,人眼只能看到这个视锥体里面的东西。
其中,aspect ratio是视口的长宽比: width/height;zNear和zFar定义相机位置与near平面和far平面之间的距离(zNear、zFar > 0),也就是比zNear近或比zFar远的东西都看不到。
2 确定相机参数position,lookAt,up
在Three.js中,camera有position,lookAt和up这三个属性。
(1)position——相机位置默认为(0,0,0);
(2)lookAt——相机焦点方向,默认为Z轴负半轴;
(3)up——默认为(0,1,0).
2.1 位置 position
//position属性:
//移动相机位置,以下是将位置移动到(0,0,30)
camera.position.set(0,0,30);
在作业0中开头直接给了个全局变量规定camera position,后面在position set的时候直接调用了。
//定义了一个全局变量
var cameraPosition = [-20, 180, 250];
//作业0中,position直接调用最开始定的全局变量
camera.position.set(cameraPosition[0], cameraPosition[1], cameraPosition[2]);
2.2 lookAt & up
如果想要改变可以用以下代码:
//up属性:
//改变时可用,以下代码是规定了x轴朝上
camera.up.x=1;
camera.up.y=0;
camera.up.z=0;
//lookAt:
//设置焦点,以下设置为朝向(0,10,0)方向
camera.lookAt(new THREE.Vector3(0,10,0));
如果场景中添加了控制器OrbitControls,想要改变相机的聚焦点设置camera.lookAt()是无效的,需要改变控制器的target属性,因此作业0中就改变的是控制器的target:
//由于设置了控制器,因此只能改变控制器的target以改变相机的lookAt方向
cameraControls.target.set(0, 1, 0);
3 轨道控制器-实现场景和鼠标交互
轨道控制器OrbitControls.js是一个three.js的拓展控件,可以实现场景与鼠标交互。利用鼠标的左右键和滚轮让场景动起来。
3.1 新建控制器
作业0中出现的这一行代码就是新建一个轨道控制器;
const cameraControls = new THREE.OrbitControls(camera, canvas);
3.1.1 控制器的围绕目标 target
轨道控制器允许照相机围绕一个目标轨道运行,目标默认为THREE.Vector3(),即(0,0,0),可通过.target = new THREE.Vector3(...)来修改:
//1.
cameraControls.target = new THREE.Vector3(0, 1, 0);
//2.
cameraControls.target.set(0, 1, 0);
同时,如果需要设置放映动画还需对target做一些调整,这里就不赘述,感兴趣可以看看:
Three.js - OrbitControls 轨道控件的围绕目标 target 参数
3.2 循环渲染场景
要想使这个控制器生效,必须循环渲染场景:requestAnimationFrame,作业0中就有循环渲染场景的代码部分:
//循环渲染场景
function mainLoop(now) {
cameraControls.update();//更新控制器
renderer.render(guiParams);//执行渲染操作
requestAnimationFrame(mainLoop);
}
requestAnimationFrame(mainLoop);
3.3 控制器提供的一些方法
OrbitControls.js控制器提供了API可以方便展示模型,例如:
3.3.1 场景自动旋转.autoRoate
//场景自动旋转
.autoRoate = boolean;
.autoRotateSpeed = float;
例如给作业0加上:
//自动旋转
cameraControls.autoRotate =true;
cameraControls.autoRotateSpeed = 10;
3.3.2 阻尼惯性.enableDamping
加上重量感,比如使用后旋转时会继续滑行一段距离。
//阻尼
.enableDamping = boolean;
.dampingFactor = float;
例如给作业0加上:
//阻尼
cameraControls.enableDamping = true;
cameraControls.dampingFactor = 0.1;
3.3.3 一些按键操作
有很多按键操作,这里就拿作业0举例,其他的操作可以根据需要搜索即可:
//按键设置
cameraControls.enableZoom = true;//摄像机缩放
cameraControls.enableRotate = true;//摄像机旋转
cameraControls.enablePan = true;//摄像机平移
//速度设置
cameraControls.rotateSpeed = 0.3;
cameraControls.zoomSpeed = 1.0;
cameraControls.panSpeed = 2.0;