当前位置: 首页 > Web前端 > HTML

使用Three.js搭建元界基础交互-大帅老元Three.js特训

时间:2023-03-27 23:42:36 HTML

大家好,今天我使用Three.js搭建一个简单的元界项目。预览效果先看预览效果:预览初始化项目首先,我们使用vite创建一个vanilla-ts项目,并安装Three.js。pnpmcreatevitethree-demo-4--templatevanilla-tscdthree-demo-4pnpmipnpminstallthreepnpmi--save-dev@types/three使用pnpmrundev启动项目,打开http://localhost:5173/,可以看到vite初始化页面。我们直接把main.ts和style.css中原来的代码删掉,把我们的代码写在里面。创建场景、相机和渲染器//创建场景、相机和渲染器constscene=newTHREE.Scene();constcamera=newTHREE.PerspectiveCamera(45,window.innerWidth/window.innerHeight,0.01,50);constrenderer=newTHREE.WebGLRenderer({antialias:true});renderer.shadowMap.enabled=true;renderer.setSize(window.innerWidth,window.innerHeight);document.body.appendChild(renderer.domElement);camera.position.设置(0、3、25);添加背景颜色和光线//添加背景颜色和光线scene.background=newTHREE.Color(0.2,0.2,0.2);constambientLight=newTHREE.AmbientLight(0xffffff,0.1);scene.add(ambientLight);constdirectionLight=newTHREE.DirectionalLight(0xffffff,0.2);scene.add(directionLight);directionLight.lookAt(newTHREE.Vector3(0,0,0));添加展馆//添加展馆letmixer:AnimationMixer;newGLTFLoader().load('../resources/models/zhangan.glb',(gltf)=>{scene.add(gltf.scene);mixer=newTHREE.AnimationMixer(gltf.scene);})渲染scene//渲染场景functionanimate(){requestAnimationFrame(animate);renderer.render(场景,相机);如果(混音器){混音器.更新(0.02);}}动画();当浏览器窗口改变时,调整window.addEventListener('resize',()=>{camera.aspect=window.innerWidth/window.innerHeightcamera.updateProjectionMatrix()renderer.setSize(window.innerWidth,window.innerHeight)})这时候打开http://localhost:5173/可以看到如下界面:添加视频我们会继续给这个展馆添加各种画面和视频newGLTFLoader().load('../resources/models/zhanguan.glb',(gltf)=>{scene.add(gltf.scene);gltf.scene.traverse((child)=>{child.castShadow=true;child.receiveShadow=true;if(child.name==='2023'){constvideo=document.createElement('video');video.src="./resources/yanhua.mp4";video.muted=true;video.autoplay=true;video.loop=true;video.play();constvideoTexture=newTHREE.VideoTexture(video);constvideoMaterial=newTHREE.MeshBasicMaterial({map:videoTexture});(childasTHREE.Mesh).material=videoMaterial;}if(child.名称==='大屏幕01'||child.name==='大屏幕02'||child.name==='操作台屏幕'||child.name==='环形画面2'){constvideo=document.createElement('video');video.src="./resources/video01.mp4";video.muted=true;video.autoplay=true;video.loop=true;视频播放();constvideoTexture=newTHREE.VideoTexture(视频);constvideoMaterial=newTHREE.MeshBasicMaterial({map:videoTexture});(子项为THREE.Mesh)。material=videoMaterial;}if(child.name==='环形屏幕'){constvideo=document.createElement('video');video.src="./resources/video02.mp4";video.muted=true;video.autoplay=true;video.loop=true;视频播放();constvideoTexture=newTHREE.VideoTexture(视频);constvideoMaterial=newTHREE.MeshBasicMaterial({map:videoTexture});(子项为THREE.Mesh)。material=videoMaterial;}if(child.name==='柱子屏'){constvideo=document.createElement('视频');video.src="./resources/yanhua.mp4";video.muted=true;video.autoplay=true;video.loop=true;视频播放();constvideoTexture=newTHREE.VideoTexture(视频);constvideoMaterial=newTHREE.MeshBasicMaterial({map:videoTexture});(子项为THREE.Mesh)。material=videoMaterial;}})mixer=newTHREE.AnimationMixer(gltf.scene);})打开http://localhost:5173/可以看到展馆内的屏风和柱子,都添加了视频。添加角色,然后将角色添加到展馆,并更新动画功能//添加角色letplayerMixer:AnimationMixer;letplayerMesh:THREE.GroupletactionWalk:AnimationActionletactionIdle:AnimationActionconstlookTarget=newTHREE.Vector3(0,2,0);newGLTFLoader().load('../resources/models/player.glb',(gltf)=>{playerMesh=gltf.scene;scene.add(gltf.scene);playerMesh.traverse((child)=>{child.receiveShadow=true;child.castShadow=true;})playerMesh.position.set(0,0,11.5);playerMesh.rotateY(Math.PI);playerMesh.add(相机);camera.position.set(0,2,-5);camera.lookAt(lookTarget);constpointLight=newTHREE.PointLight(0xffffff,1.5);playerMesh.add(点光源);pointLight.position.set(0,1.8,-1);playerMixer=newTHREE.AnimationMixer(gltf.scene);//角色行走时的状态constclipWalk=THREE.AnimationUtils.subclip(gltf.animations[0],'walk',0,30);actionWalk=playerMixer.clipAction(clipWalk);//角色停止时的状态constclipIdle=THREE.AnimationUtils.subclip(gltf.animations[0],'idle',31,281);actionIdle=playerMixer.clipAction(clipIdle);actionIdle.play();});functionanimate(){requestAnimationFrame(animate);renderer.render(场景,相机);如果(混音器){mixer.update(0.02);}if(playerMixer){playerMixer.update(0.015);}}此时,页面显示如下:控制角色行走,让鼠标控制相机旋转,按键盘上的W让角色在展厅内行走letisWalk=false;constplayerHalfHeight=newTHREE.Vector3(0,0.8,0);window.addEventListener('keydown',(e)=>{if(e.key==='w'){constcurPos=playerMesh.position.clone();playerMesh.translateZ(1);constfrontPos=playerMesh.position.clone();playerMesh.translateZ(-1);常量frontVector3=frontPos.sub(curPos).normalize()constraycasterFront=newTHREE.Raycaster(playerMesh.position.clone().add(playerHalfHeight),frontVector3);constcollisionResultsFrontObjs=raycasterFront.intersectObjects(scene.children);如果(collisionResultsFrontObjs&&collisionResultsFrontObjs[0]&&collisionResultsFrontObjs[0].distance>1){playerMesh.translateZ(0.1);}if(!isWalk){crossPlay(actionIdle,actionWalk);是步行=真;}}})window.addEventListener('keyup',(e)=>{if(e.key==='w'){crossPlay(actionWalk,actionIdle);isWalk=false;}});letpreClientX:number;window.addEventListener('mousemove',(e)=>{if(preClientX&&playerMesh){playerMesh.rotateY(-(e.clientX-preClientX)*0.01);}preClientX=e.clientX;});functioncrossPlay(curAction:AnimationAction,newAction:AnimationAction){curAction.fadeOut(0.3);newAction.reset();newAction.setEffectiveWeight(1);newAction.play();newAction.fadeIn(0.3);}添加阴影,最后为亭子设置阴影//设置阴影directionLight.castShadow=true;directionLight.shadow.mapSize.width=2048;directionLight.shadow.mapSize.height=2048;const阴影距离=20;方向灯。shadow.camera.near=0.1;directionLight.shadow.camera.far=40;directionLight.shadow.camera.left=-shadowDistance;directionLight.shadow.camera.right=shadowDistance;directionLight.shadow.camera.top=shadowDistance;directionLight.shadow.camera.bottom=-shadowDistance;directionLight.shadow.bias=-0.001;好了,大功告成,请点击预览效果:预览仓库地址仓库地址