Three.js光源、相机知识梳理
光源
Threejs场景对象Scene
主要是由模型对象和光源对象Light
构成,在实际开发过程中,多数三维场景往往需要设置光源对象,Threejs虚拟光源是对自然界光照的模拟。
1、环境光(AmbientLight):会均匀的照亮场景中的所有物体。环境光不能用来投射阴影,因为它没有方向。
2、平行光(DirectionalLight):它发出的光线都是平行的。经常用平行光来模拟太阳光的效果。
3、点光源(PointLight):常见的例子是模拟一个灯泡发出的光。
4、聚光灯(SpotLight):从一个方向上的一个点发出,照射范围在三维空间中构成一个圆锥体,它离光越远,它的尺寸就越大。
阴影
支持阴影的有:平行光、点光源、聚光灯。
由于阴影的计算是非常消耗性能的,因此阴影默认是不计算不显示的;需要显示阴影,有以下几个条件:
1、渲染器需要开启阴影计算 renderer.shadowMap.enabled = true; 2、光照支持阴影,光照开启阴影 light.castShadow = true; 3、需要计算阴影的物体开启阴影 cube.castShadow = true; 4、需要有接收阴影的物体 plane.receiveShadow = true;
相机
机械、工业设计领域常常采用正投影(平行投影),大型游戏场景往往采用透视投影(中心投影)。
对于正投影而言,一条直线放置的角度不同,投影在投影面上面的长短不同;对于透视投影而言,投影的结果除了与几何体的角度有关,还和距离相关, 人的眼睛观察世界就是透视投影,比如你观察一条铁路距离越远你会感到两条轨道之间的宽度越小。
正投影相机(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从距离相机多远的位置开始渲染,
//far距离相机多远的位置截止渲染
参数left
与right
、参数top
与bottom
互为相反数,这样做的目的是lookAt
指向的对象能够显示在canvas画布的中间位置。
透视投影相机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 )
//fov表示视场,所谓视场就是能够看到的角度范围,人的眼睛大约能够看到180度的视场,视角大小设置要根据具体应用,一般游戏会设置60~90度
//aspect表示渲染窗口的长宽比
效果对比:
图一为正投影,图二为透视投影
相机位置.posiiotn
和.lookAt(相机拍摄目标位置)
camera.position可以设置相机的位置。
camera.lookAt设置相机拍摄目标的位置。你希望相机对准哪个对象,就返回那个对象的位置属性.posiiotn。所以
等同于scene.position,等同于mesh.position。
camera.position.set(200, 300, 200); //设置相机位置 camera.lookAt(scene.position); //设置相机方向(指向的场景对象)
相机位置与观察目标位置间隔距离越小,场景中的三维模型放大倍数越大,准确地说是透视投影相机可以拍摄的范围更小。
如果是观察一个产品外观效果,相机就位于几何体的外面,如果是室内漫游预览,就把相机放在房间三维模型的内部。
窗口尺寸变化(自适应渲染)
正投影相机OrthographicCamera自适应渲染
// 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 (); };