文章目录
9、相机对象(投影方式)
9.1 正投影和透视投影相机
正投影和透视投影简单解释
正投影相机对象 OrthographicCamera
/**
* 正投影相机设置
*/
var width = window.innerWidth; //窗口宽度
var height = window.innerHeight; //窗口高度
var k = width / height; //窗口宽高比
var s = 150; //三维场景显示范围控制系数,系数越大,显示的范围越大
//创建相机对象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
camera.position.set(200, 300, 200); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
// 构造函数格式
OrthographicCamera( left, right, top, bottom, near, far )
参数(属性) | 含义 |
---|---|
left | 渲染空间的左边界 |
right | 渲染空间的右边界 |
top | 渲染空间的上边界 |
bottom | 渲染空间的下边界 |
near | near属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。 默认值0.1 |
far | far属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小小,会有部分场景看不到。 默认值1000 |
三维场景中坐标值不在三维空间中的网格模型不会被渲染出来,会被剪裁掉,比如你把上面代码中far参数的值从1000更改为420,你会发现长方体的一部分无法显示。
注意
左右边界的距离与上下边界的距离比值与画布的渲染窗口的宽高比例要一致,否则三维模型的显示效果会被单方向不等比例拉伸
透视投影相机 PerspectiveCamera
/**
* 透视投影相机设置
*/
var width = window.innerWidth; //窗口宽度
var height = window.innerHeight; //窗口高度
/**透视投影相机对象*/
var camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000);
camera.position.set(200, 300, 200); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
PerspectiveCamera( fov, aspect, near, far )//构造函数PerspectiveCamera格式
参数 | 含义 | 默认值 |
---|---|---|
fov | fov表示视场,所谓视场就是能够看到的角度范围,人的眼睛大约能够看到180度的视场,视角大小设置要根据具体应用,一般游戏会设置60~90度 | 45 |
aspect | aspect表示渲染窗口的长宽比,如果一个网页上只有一个全屏的canvas画布且画布上只有一个窗口,那么aspect的值就是网页窗口客户区的宽高比 | window.innerWidth/window.innerHeight |
near | near属性表示的是从距离相机多远的位置开始渲染,一般情况会设置一个很小的值。 | 0.1 |
far | far属性表示的是距离相机多远的位置截止渲染,如果设置的值偏小,会有部分场景看不到 | 1000 |
相机位置 .posiiotn 和 .lookAt (相机拍摄目标位置)
相机Camera的基类是Object3D,相机对象Camera具有位置属性.posiiotn,通过位置属性.posiiotn可以设置相机的位置。
.lookAt()方法用来指定相机拍摄对象的坐标位置,.lookAt()方法的参数是表示位置坐标的三维向量对象Vector3,所以.lookAt()方法的参数可以通过代码new THREE.Vector3(x,y,z)设置。实际开发的时候,你希望相机对准哪个对象,就返回那个对象的位置属性.posiiotn,比如上面代码中的scene.position, 就表示返回场景scene的位置坐标,如果把scene.position换成某个网格模型对象的位置就是mesh.position,mesh.position表示网格模型mesh的本地位置坐标。通过相机观察点的位置和.lookAt()方法指向的位置就可以计算出相机的拍摄角度,本质上就是计算出相机对象的视图矩阵.matrixWorldInverse。
对于透视投影而言,相机位置与lookAt指向的观察目标位置间隔距离越小,场景中的三维模型放大倍数越大,准确地说是透视投影相机可以拍摄的范围更小,同时场景Scene中超出的相机参数约束范围的部分会被剪裁掉, 比如更改上面代码camera.position.set(100,200,200);为(20,20,20),测试结果你会发现立方体几何体放大显示,超出区域被剪裁。
相机位置放置
如果是观察一个产品外观效果,相机就位于几何体的外面,如果是室内漫游预览,就把相机放在房间三维模型的内部。
9.2 窗口变化自适应渲染
视图矩阵 .matrixWorldInverse 和投影矩阵 .projectionMatrix
影响视图矩阵.matrixWorldInverse计算的相关代码,无论透视投影相机还是正投影相机都一样。
camera.position.set(200, 300, 200); //设置相机位置
camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
影响投影矩阵.projectionMatrix计算相机参数的相关代码
// 正投影相机对象
var camera = new THREE.OrthographicCamera(-s * k, s * k, s, -s, 1, 1000);
// 透视投影相机对象
var camera = new THREE.PerspectiveCamera(60, width / height, 1, 1000);
正投影相机 OrthographicCamera 自适应渲染
比如全屏渲染的时候,为了适应窗口的大小变化,要重新设置相机对象和渲染器对象的参数,不需要在渲染函数render中周期性更新,只需要通过窗口事件window.onresize来触发一个函数,然后在函数中更新相机Camera和渲染器WebGLRenderer的参数。
渲染区域变化了,要通过Three.js渲染器.setSize()方法重置渲染器渲染尺寸。
// onresize 事件会在窗口被调整大小时发生
window.onresize=function(){
// 重置渲染器输出画布canvas尺寸
renderer.setSize(window.innerWidth,window.innerHeight);
// 重置相机投影的相关参数
k = window.innerWidth/window.innerHeight;//窗口宽高比
camera.left = -s*k;
camera.right = s*k;
camera.top = s;
camera.bottom = -s;
// 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
// 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)
// 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
camera.updateProjectionMatrix ();
};
透视投影相机 PerspectiveCamera 自适应渲染
// onresize 事件会在窗口被调整大小时发生
window.onresize=function(){
// 重置渲染器输出画布canvas尺寸
renderer.setSize(window.innerWidth,window.innerHeight);
// 全屏情况下:设置观察范围长宽比aspect为窗口宽高比
camera.aspect = window.innerWidth/window.innerHeight;
// 渲染器执行render方法的时候会读取相机对象的投影矩阵属性projectionMatrix
// 但是不会每渲染一帧,就通过相机的属性计算投影矩阵(节约计算资源)
// 如果相机的一些属性发生了变化,需要执行updateProjectionMatrix ()方法更新相机的投影矩阵
camera.updateProjectionMatrix ();
};