新的一年,从threejs开始吧~

装置threejs

npm i three

引入threejs

// 援用Threejsimport * as THREE from 'three';// 引入GLTF加载器 用于载入glTF资源import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';

threejs根本元素

// 根本元素1、定义场景const scene = new THREE.Scene();// 根本元素2、相机   PerspectiveCamera-透视相机近大远小 OrthographicCamera-正交相机远近同样大小const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 50);camera.position.set(5, 10, 25);// 根本元素3、灯光  ambientLight-环境光 directionalLight-方向光 pointLight-点光源 spotLight-聚光灯 hemisphereLight-半球光const ambientLight = new THREE.AmbientLight(0xffffff, 0.1);scene.add(ambientLight);// 根本元素4、几何体const boxGeometry = new THREE.BoxGeometry(1, 1, 1);// 根本元素5、材质 MeshBasicMaterial-根底材质 MeshStandardMaterial-PBR材质const boxMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });// mesh-网格 几何体是不能被渲染的,只有几何体和材质联合成网格能力被渲染到屏幕上const boxMesh = new THREE.Mesh(boxGeometry, boxMaterial);// 场景中增加meshscene.add(boxMesh);

残缺代码

// 援用Threejsimport * as THREE from 'three';// 引入GLTF加载器 用于载入glTF资源import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader';let mixer;let playerMixer;// 根本元素1、定义场景const scene = new THREE.Scene();// 根本元素2、相机   PerspectiveCamera-透视相机近大远小 OrthographicCamera-正交相机远近同样大小const camera = new THREE.PerspectiveCamera(45, window.innerWidth / window.innerHeight, 0.01, 50);camera.position.set(5, 10, 25);scene.background = new THREE.Color(0.2, 0.2, 0.2);// 根本元素3、灯光  ambientLight-环境光 directionalLight-方向光 pointLight-点光源 spotLight-聚光灯 hemisphereLight-半球光const ambientLight = new THREE.AmbientLight(0xffffff, 0.1);scene.add(ambientLight);const directionLight = new THREE.DirectionalLight(0xffffff, 0.2);scene.add(directionLight);directionLight.lookAt(new THREE.Vector3(0, 0, 0));directionLight.castShadow = true;directionLight.shadow.mapSize.width = 2048;directionLight.shadow.mapSize.height = 2048;const shadowDistance = 20;directionLight.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;// 根本元素4、几何体// const boxGeometry = new THREE.BoxGeometry(1, 1, 1);// 根本元素5、材质 MeshBasicMaterial-根底材质 MeshStandardMaterial-PBR材质// const boxMaterial = new THREE.MeshBasicMaterial({ color: 0x00ff00 });// mesh-网格 几何体是不能被渲染的,只有几何体和材质联合成网格能力被渲染到屏幕上// const boxMesh = new THREE.Mesh(boxGeometry, boxMaterial);// 场景中增加mesh// scene.add(boxMesh);// 坐标系// const axesHelper = new THREE.AxesHelper(10);// scene.add(axesHelper);// 渲染器 将元素渲染进去能力看见const renderer = new THREE.WebGLRenderer({ antialias: true });renderer.shadowMap.enabled = true;renderer.setSize(window.innerWidth, window.innerHeight);document.body.appendChild(renderer.domElement);let playerMesh;let actionWalk, actionIdle;const lookTarget = new THREE.Vector3(0, 2, 0);// 加载人物模型new GLTFLoader().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);    camera.position.set(0, 2, -5);    camera.lookAt(lookTarget);    const pointLight = new THREE.PointLight(0xffffff, 1.5);    playerMesh.add(pointLight);    pointLight.position.set(0, 1.8, -1);    playerMixer = new THREE.AnimationMixer(gltf.scene);    const clipWalk = THREE.AnimationUtils.subclip(gltf.animations[0], 'walk', 0, 30);    actionWalk = playerMixer.clipAction(clipWalk);    // actionWalk.play();    const clipIdle = THREE.AnimationUtils.subclip(gltf.animations[0], 'idle', 31, 281);    actionIdle = playerMixer.clipAction(clipIdle);    actionIdle.play();});let isWalk = false;const playerHalfHeight = new THREE.Vector3(0, 0.8, 0);// 监听键盘事件 按下w/s管制人物后退/后退window.addEventListener('keydown', (e) => {    if (e.key === 'w') {        const curPos = playerMesh.position.clone();        playerMesh.translateZ(1);        const frontPos = playerMesh.position.clone();        playerMesh.translateZ(-1);        const frontVector3 = frontPos.sub(curPos).normalize();        const raycasterFront = new THREE.Raycaster(playerMesh.position.clone().add(playerHalfHeight), frontVector3);        const collisionResultsFrontObjs = raycasterFront.intersectObjects(scene.children);        // 碰撞检测        if (collisionResultsFrontObjs && collisionResultsFrontObjs[0] && collisionResultsFrontObjs[0].distance > 1) {            // 管制挪动            playerMesh.translateZ(0.1);        }        if (!isWalk) {            // 人物后退动作            crossPlay(actionIdle, actionWalk);            isWalk = true;        }    }    if (e.key === 's') {        playerMesh.translateZ(-0.1);    }});// 监听键盘事件 抬起w键管制人物进行window.addEventListener('keyup', (e) => {    if (e.key === 'w') {        // 工作站立动作        crossPlay(actionWalk, actionIdle);        isWalk = false;    }});let preClientX;// 监听鼠标 管制人物挪动方向window.addEventListener('mousemove', (e) => {    if (preClientX && playerMesh) {        playerMesh.rotateY(-(e.clientX - preClientX) * 0.01);    }    preClientX = e.clientX;});// 加载场景模型new GLTFLoader().load('../resources/models/zhanguan.glb', (gltf) => {    // console.log(gltf);    scene.add(gltf.scene);    // 获取每一个元素增加视频动画    gltf.scene.traverse((child) => {        // console.log(child.name);        child.castShadow = true;        child.receiveShadow = true;        if (child.name === '2023') {            const video = document.createElement('video');            video.src = './resources/yanhua.mp4';            video.muted = true;            video.autoplay = 'autoplay';            video.loop = true;            video.play();            const videoTexture = new THREE.VideoTexture(video);            const videoMaterial = new THREE.MeshBasicMaterial({ map: videoTexture });            child.material = videoMaterial;        }        if (child.name === '大屏幕01' || child.name === '大屏幕02' || child.name === '操作台屏幕' || child.name === '环形屏幕2') {            const video = document.createElement('video');            video.src = './resources/video01.mp4';            video.muted = true;            video.autoplay = 'autoplay';            video.loop = true;            video.play();            const videoTexture = new THREE.VideoTexture(video);            const videoMaterial = new THREE.MeshBasicMaterial({ map: videoTexture });            child.material = videoMaterial;        }        if (child.name === '环形屏幕') {            const video = document.createElement('video');            video.src = './resources/video02.mp4';            video.muted = true;            video.autoplay = 'autoplay';            video.loop = true;            video.play();            const videoTexture = new THREE.VideoTexture(video);            const videoMaterial = new THREE.MeshBasicMaterial({ map: videoTexture });            child.material = videoMaterial;        }        if (child.name === '柱子屏幕') {            const video = document.createElement('video');            video.src = './resources/yanhua.mp4';            video.muted = true;            video.autoplay = 'autoplay';            video.loop = true;            video.play();            const videoTexture = new THREE.VideoTexture(video);            const videoMaterial = new THREE.MeshBasicMaterial({ map: videoTexture });            child.material = videoMaterial;        }    });    mixer = new THREE.AnimationMixer(gltf.scene);    const clips = gltf.animations; // 播放所有动画    clips.forEach(function (clip) {        const action = mixer.clipAction(clip);        action.loop = THREE.LoopOnce;        // 停在最初一帧        action.clampWhenFinished = true;        action.play();    });});function crossPlay(curAction, newAction) {    curAction.fadeOut(0.3);    newAction.reset();    newAction.setEffectiveWeight(1);    newAction.play();    newAction.fadeIn(0.3);}// 动画function animate() {    requestAnimationFrame(animate);    renderer.render(scene, camera);    if (mixer) {        mixer.update(0.02);    }    if (playerMixer) {        playerMixer.update(0.015);    }}animate();

素材、源码和演示成果稍后附在评论区,有什么问题欢送留言

以上就是在threejs特训中学到的0根底实现人物看展成果,退出猿创营 (v:dashuailaoyuan),一起交流学习吧~