1.为项目创建一个目录,并在项目根目录下执行
npmcreatevite@latest2、APP.vue
//两个参数分别为几何体geometry、材质materialconstmesh=newTHREE.Mesh(geometry,material);//网格模型对象Mesh模型位置.position实际生活中,一个物体往往是有位置的,对于threejs而言也是一样的,你可以通过位置属性.position定义网格模型Mesh在三维场景Scene中的位置。
constmesh=newTHREE.Mesh(geometry,material);//网格模型对象Mesh//设置网格模型在三维空间中的位置坐标,默认是坐标原点mesh.position.set(0,10,0);.add()方法在threejs中你创建了一个表示物体的虚拟对象Mesh,需要通过.add()方法,把网格模型mesh添加到三维场景scene中。
scene.add(mesh);后续内容写到这里,我知道你已经迫不及待想执行代码看看渲染效果了,那么你需要看看后面两节课关于相机Camera和渲染器Renderer的介绍
Threejs如果想把三维场景Scene渲染到web网页上,还需要定义一个虚拟相机Camera,就像你生活中想获得一张照片,需要一台用来拍照的相机。
透视投影相机PerspectiveCamera本质上就是在模拟人眼观察这个世界的规律。
//实例化一个透视投影相机对象constcamera=newTHREE.PerspectiveCamera();相机位置.posiiotn生活中用相机拍照,你相机位置不同,拍照结果也不同,threejs中虚拟相机同样如此。
比如有一间房子,你拿着相机站在房间里面,看到的是房间内部,站在房子外面看到的是房子外面效果。
相机对象Camera具有位置属性.posiiotn,通过位置属性.posiiotn可以设置相机的位置。
//相机在Three.js三维坐标系中的位置//根据需要设置相机位置具体值camera.position.set(200,200,200);相机观察目标.lookAt()你用相机拍照你需要控制相机的拍照目标,具体说相机镜头对准哪个物体或说哪个坐标。对于threejs相机而言,就是设置.lookAt()方法的参数,指定一个3D坐标。
你可以把三维场景中长方体mesh想象为一个房间,然后根据相机位置和长方体位置尺寸对比,判断两者相对位置。你可以发现设置相机坐标(200,200,200),位于长方体外面一处位置。
你生活中相机拍照的照片是有大小的,对于threejs而言一样,需要定义相机在网页上输出的Canvas画布(照片)尺寸,大小可以根据需要定义,这里先随机定义一个尺寸。
Canvas画布
//定义相机输出画布的尺寸(单位:像素px)constwidth=800;//宽度constheight=500;//高度透视投影相机PerspectiveCamera:视锥体透视投影相机的四个参数fov,aspect,near,far构成一个四棱台3D空间,被称为视锥体,只有视锥体之内的物体,才会渲染出来,视锥体范围之外的物体不会显示在Canvas画布上。
//width和height用来设置Three.js输出的Canvas画布尺寸(像素px)constwidth=800;//宽度constheight=500;//高度//30:视场角度,width/height:Canvas画布宽高比,1:近裁截面,3000:远裁截面constcamera=newTHREE.PerspectiveCamera(30,width/height,1,3000);PerspectiveCamera参数介绍:
THREE.AxesHelper()的参数表示坐标系坐标轴线段尺寸大小,你可以根据需要改变尺寸。
通过模型的位置、尺寸设置,加深3D坐标系的概念。
测试:设置长方体xyz不同方向尺寸
//设置几何体长宽高,也就是x、y、z三个方向的尺寸//对比三个参数分别对应xyz轴哪个方向newTHREE.BoxGeometry(100,60,20);测试:改变位置
相机放在x轴负半轴,目标观察点是坐标原点,这样相当于相机的视线是沿着x轴正方向,只能看到长方体的一个矩形平面。
camera.position.set(-1000,0,0);camera.lookAt(0,0,0);//相机视线沿着x轴负半轴,mesh位于相机后面,自然看不到camera.position.set(-1000,0,0);camera.lookAt(-2000,0,0);相机far偏小,mesh位于far之外,物体不会显示在画布上。
实际生活中物体表面的明暗效果是会受到光照的影响,比如晚上不开灯,你就看不到物体,灯光比较暗,物体也比较暗。在threejs中,咱们用网格模型Mesh模拟生活中物体,所以threejs中模拟光照Light对物体表面的影响,就是模拟光照Light对网格模型Mesh表面的影响。
你可以打开课件中案例源码,对比有光照和无光照两种情况,网格模型Mesh表面的差异。
threejs提供的网格材质,有的受光照影响,有的不受光照影响。
一个立方体长方体使用MeshLambertMaterial材质,不同面和光线夹角不同,立方体不同面就会呈现出来不同的明暗效果。
//点光源:两个参数分别表示光源颜色和光照强度//参数1:0xffffff是纯白光,表示光源颜色//参数2:1.0,表示光照强度,可以根据需要调整constpointLight=newTHREE.PointLight(0xffffff,1.0);除了通过THREE.PointLight的参数2设置光照强度,你可以可以直接访问光照强度属性.intensity设置。
pointLight.decay=0.0;//设置光源不随距离衰减【扩展提醒】:如果使用默认衰减2.0,不同版本可能有差异,对于部分threejs新版本,有时候你可能看不到光源效果,这时候可以把光照强度加强试试看,如果你的版本不影响,就不用加强光照强度(根据版本情况灵活对应)。
注意光源位置尺寸大小:如果你希望光源照在模型的外表面,那你就需要把光源放在模型的外面。
scene.add(pointLight);//点光源添加到场景中设置好上面所有代码,你现在可以执行代码,用浏览器查看渲染效果。
pointLight.position.set(400,200,300);相机控件OrbitControls平时开发调试代码,或者展示模型的时候,可以通过相机控件OrbitControls实现旋转缩放预览效果。
你可以打开课件案例源码测试下效果。
相机,让哪一个相机围绕目标运动。默认目标是原点。立方体在原点处。
渲染的画布dom对象,用于监听鼠标事件控制相机的围绕运动。
OrbitControls本质上就是改变相机的参数,比如相机的位置属性,改变相机位置也可以改变相机拍照场景中模型的角度,实现模型的360度旋转预览效果,改变透视投影相机距离模型的距离,就可以改变相机能看到的视野范围。
预览观察:可以借助相机控件OrbitControls旋转缩放三维场景便于预览点光源位置
//光源辅助观察constpointLightHelper=newTHREE.PointLightHelper(pointLight,10);scene.add(pointLightHelper);改变点光源位置,观察光照效果变化。
//对比不同入射角,mesh表面对光照的反射效果directionalLight.position.set(100,0,0);directionalLight.position.set(0,100,0);directionalLight.position.set(100,100,100);directionalLight.position.set(100,60,50);//directionalLight.target默认指向坐标原点动画渲染循环threejs可以借助HTML5的API请求动画帧window.requestAnimationFrame实现动画渲染。
//requestAnimationFrame实现周期性循环执行//requestAnimationFrame默认每秒钟执行60次,但不一定能做到,要看代码的性能leti=0;functionrender(){i+=1;console.log('执行次数'+i);requestAnimationFrame(render);//请求再次执行函数render}render();备注说明:对于部分高刷新率的电脑硬件设备,.requestAnimationFrame每秒钟默认调用函数执行次数也是有可能超过60次的,比如你的电脑显卡、显示器等硬件能够支持144hz刷新频率,.requestAnimationFrame的每秒执行上限,也可以接近144帧率。
动画说白了就是一张张照片,连起来依次展示,这样就形成一个动画效果,只要帧率高,人的眼睛就感觉不到卡顿,是连续的视频效果。
threejs渲染输出的结果就是一个Cavnas画布,canvas画布也是HTML的元素之一,这意味着three.js渲染结果的布局和普通web前端习惯是一样的。
通过renderer.domElement属性可以访问threejs的渲染结果,也就是HTML的元素canvas画布。
你可以把threejs的渲染结果renderer.domElement,插入到web页面上任何一个元素中,只要符合你项目的布局规则即可。
设置渲染器锯齿属性.antialias的值可以直接在参数中设置,也可通过渲染器对象属性设置。
constrenderer=newTHREE.WebGLRenderer({antialias:true,});或
注意:注意你的硬件设备设备像素比window.devicePixelRatio刚好是1,那么是否执行.setPixelRatio()不会有明显差异,不过为了适应不同的硬件设备屏幕,通常需要执行该方法。
学习dat.gui.js也不仅仅是为了学习dat.gui.js,也是建立一种思想,就是threejs三维空间的很多参数,不是心算出来的,往往需要可视化的方式调试出来。
你可以通过npm或github方式获得dat.gui.js库,当然为了学习方便,threejs官方案例扩展库中也提供了gui.js,你可以直接使用。
格式:.add(控制对象,对象具体属性,其他参数)
其他参数,可以一个或多个,数据类型也可以不同,gui会自动根据参数形式,自动生成对应的交互界面。
参数3和参数4,分别是一个数字,交互界面是一个鼠标可以拖动的拖动条,可以在一个区间改变属性的值
执行gui.add(obj,'x',0,100);你可以发现右上角gui界面增加了新的内容,可以控制obj对象x属性的新交互界面。
光源对象具有一个光照强度属性.intensity,可以通过gui拖动条改变该属性。
gui.add(mesh.position,'x',0,180);gui.add(mesh.position,'y',0,180);gui.add(mesh.position,'z',0,180);gui调试界面2-颜色命名等给大家介绍gui.js库更多的方法。
.add()创建的交互界面,会默认显示所改变属性的名字,为了通过交互界面更好理解你改变的某个对象属性,你可以通过.name()方法改变gui生成交互界面显示的内容。
constobj={color:0x00ffff,};//.addColor()生成颜色值改变的交互界面gui.addColor(obj,'color').onChange(function(value){mesh.material.color.set(value);});gui调试3-下拉菜单、单选框前面大家学过通过.add()方法可以添加一个拖动条用来改变对象的某个属性,本节课给大家介绍.add()方法创建新的UI交互界面,比如下拉菜单、单选框。
格式:add(控制对象,对象具体属性,其他参数)
gui.add(obj,'bool').name('旋转动画');//渲染循环functionrender(){//当gui界面设置obj.bool为true,mesh执行旋转动画if(obj.bool)mesh.rotateY(0.01);renderer.render(scene,camera);requestAnimationFrame(render);}render();gui.js库(分组)当GUI交互界面需要控制的属性比较多的时候,为了避免混合,可以适当分组管理,这样更清晰。
gui交互界面不分组,只有一个默认的总的菜单。
.addFolder()返回的子文件夹对象,同样具有gui对象的.add()、.onChange()、.addColor()等等属性。