前言之前跟着大帅断断续续的学习threejs,并没有投入太多的精力,不过也学习了一些Threejs的技巧和api。最近学习了如何使用Blender进行3D建模,添加动画,以及如何用胖达在Threejs中显示和控制3D模型,解答了我的疑惑。原来,一些看似复杂的3D项目竟然可以如此轻松实现。下面以甜甜圈案例了解threejs安装及基本应用分析需求。要实现动画中的甜甜圈效果,按照代码层面的思路,必须要用threejs创建一个甜甜圈,然后改变它的位置来实现动画。效果好像还可以,其实自己实现这个甜甜圈和动画效果太复杂了。这不,庞达老师给我们带来了切实可行的解决方案。我们可以去3D模型资源网站下载一些甜甜圈模型,然后用Blender将模型的细节处理成我们想要的形状。由于之前接触过3DMAX,感觉这部分的处理大同小异,比如点线面处理,材质贴图等等。在Blender中,我们不仅可以建立模型,还可以为模型添加帧动画,这样这样实现的模型在Threejs中引入后可以很方便的实现其动画。通过npm实现下载Threejsnpmithree项目中引用Threejsimport*asTHREEfrom'three';createsceneandcameraandrenderer,addrenderertodom/***createsceneandcameraandrenderer*/constscene=newTHREE.Scene()constcamera=newTHREE.PerspectiveCamera(75,//广角window.innerWidth/window.innerHeight,//压缩比0.01,//场景的近距离锥体10//场景的远距离锥体)constrenderer=newTHREE.WebGLRenderer({antialias:true//抗锯齿(会比较消耗性能开启时)})//设置渲染器尺寸renderer.setSize(window.innerWidth,window.innerHeight)//将渲染器添加到domdocument.body.appendChild(renderer.domElement)创建环境光/***创建环境光*/constambientLight=newTHREE.AmbientLight(0xffffff,0.2);场景。添加(环境光);创建几何,测试让我们看看我们的场景构建是否成功/***创建几何(用于测试)*/constboxGeometry=newTHREE.BoxGeometry(1,1,1)constboxMaterial=newTHREE.MeshBasicMaterial({color:0xdedede})constboxMesh=newTHREE.Mesh(boxGeometry,boxMaterial)scene.add(boxMesh)创建关键帧动画,渲染构建的场景和相机/***创建关键帧动画*/functionanimate(){requestAnimationFrame(animate)renderer.render(scene,camera)}animate()这样一个基本的场景搭建好了,但是这时候查看的时候,会发现页面是黑的,我们为了测试创建的聚合也不见了。事实上,相机的初始位置是几何体内部的(0,0,0),因此我们需要移动它。Cameraposition//放置相机位置,或者在盒子里,一块黑色的camera.position.set(0,0,2)创建一个控制器来控制相机import{OrbitControls}from"three/examples/jsm/controls/OrbitControls";//....//创建控件constcontrols=newOrbitControls(camera,renderer.domElement)functionanimate(){//....controls.update()}此时,效果如下添加hdr环境贴图/***添加hdr环境贴图*/newRGBELoader().load('../resources/sky.hdr',function(texture){scene.background=texture;texture.mapping=THREE.EquirectangularReflectionMapping;scene.environment=texture;renderer.outputEncoding=THREE.sRGBEncoding;renderer.render(scene,camera);});这里布置场景,然后添加3D模型import{GLTFLoader}from"three/examples/jsm/loaders/GLTFLoader";//....letdonuts;newGLTLoader().load('../resources/models/donuts.glb',(gltf)=>{console.log(gltf);scene.add(gltf.scene);donuts=gltf.scene;})效果如下,这样我们的3D模型就是加载,是不是很简单但是现在甜甜圈还是没有动画效果,怎么给它加上动画效果呢,我们可能会想到获取每个甜甜圈对象然后手动写代码给它加上动画效果,然后扩展我们如何获取Donut对象,打印取出下面加载的模型以查看它包含哪些属性。我们可以看到场景对象包含一些Mesh。这些实际上是我们在Blender中构建的模型。我们可以通过改变这些MeshEffect的位置来实现动画。但是我们也看到动画中有6个AnimationClips。事实上,这6个AnimationClips对应于我们在Blender中为6个甜甜圈创建的动画。这6个AnimationClips包含了6个甜甜圈的动画信息。下面看看如何使用letdonuts;letmixer;newGLTFLoader().load('../resources/models/donuts.glb',(gltf)=>{console.log(gltf);scene.add(gltf.scene);donuts=gltf.scene;mixer=newTHREE.AnimationMixer(gltf.scene);constclips=gltf.animations;//播放所有动画clips.forEach(function(clip){constaction=mixer.clipAction(clip);action.loop=THREE.LoopOnce;//在最后一帧停止action.clampWhenFinished=true;action.play();});})//....functionanimate(){//....如果(混音器){mixer.update(0.02);}}这样一个简单的甜甜圈案例就实现了总结这个案例虽然比较简单,但是可以让我们了解程序开发和美术资源是如何协同工作的,学习3D模型在Threejs中是如何使用的,相信可以帮助大家打开Threejs的大门。那么如何实现更复杂的元宇宙场景呢?如何加载角色模型来控制它的移动?有兴趣的可以加入源创影(v:dashhuailaoyuan)一起交流学习。
