今天使用3DMax建模软件进行3D模型的制作,并且加入动画,通过threejs将模型及其动画部署在VUE框架上。
一、环境及其开发包版本
1. VUE:3.3.4
2. threejs:0.158.0
3. vite:4.4.11
4. 3DMax2021
5. pycharm2021专业版
二、3DMax模型制作
简单制作一个小植物和一个水壶,实现浇水后植物长大的动画。
UV展开,加个材质,上个颜色。
三、项目搭建
项目使用VUE框架。使用命令“npm init vue@latest”创建一个vue项目,并使用命令“npm i three”安装threejs。
在vue文件中引入JavaScript文件。
ttt.js文件代码如下:
import * as THREE from "three"import {OrbitControls} from "three/addons/controls/OrbitControls.js";import {GLTFLoader} from "three/addons/loaders/GLTFLoader.js";let width = window.innerWidthlet height = window.innerHeightconst scene = new THREE.Scene()scene.background = new THREE.Color(0x7F7F61)const camera = new THREE.PerspectiveCamera(60, width / height)camera.position.set(-3, 10, 10)camera.lookAt(0, 0, 0)scene.add(camera)const aLignt = new THREE.AmbientLight(new THREE.Color(0xffffff), 2)scene.add(aLignt)const pointLight = new THREE.PointLight(new THREE.Color(0xffffff), 2, 0, 0)pointLight.position.set(15, 15, 15)scene.add(pointLight)const axes = new THREE.AxesHelper(50)// scene.add(axes)const spriteMaterial = new THREE.SpriteMaterial({ map: new THREE.TextureLoader().load('./src/assets/水滴.png'), transparent: true, opacity: 0.3})const groups = new THREE.Group()let spritey = 2.91let spriteflag = falsefor (let i = 0; i < 200; i++) { const sprite = new THREE.Sprite(spriteMaterial) sprite.scale.set(0.1, 0.2, 0.1) const x = Math.random() - Math.random() const y = Math.random() * spritey // const y = spritey const z = Math.random() - Math.random() sprite.position.set(x, y, z) groups.add(sprite)}let ganzi, yezi1, yezi2, yezi3, yezi4, huapenconst group = new THREE.Group()group.name = 'group'let geometry, meshlet track1, track2, track3, track4, track5let clip, mixer, actionAnimation, clockconst loader = new GLTFLoader();loader.load('./src/assets/1111.glb', gltf => { console.log(gltf) // gltf.scene.scale.set(5,5,5) group.add(gltf.scene) scene.add(group) huapen = group.getObjectByName('花盆') yezi1 = group.getObjectByName('叶子1') yezi2 = group.getObjectByName('叶子2') yezi3 = group.getObjectByName('叶子3') yezi4 = group.getObjectByName('叶子4') ganzi = group.getObjectByName('杆子') mixer = new THREE.AnimationMixer(group) actionAnimation = mixer.clipAction(gltf.animations[0]) actionAnimation.timeScale = 0 actionAnimation.clampWhenFinished = true actionAnimation.loop = THREE.LoopOnce actionAnimation.play() clock = new THREE.Clock()})let mixershuihu, actionanimationshuihu, c1loader.load('./src/assets/11111.glb', gltf => { console.log(gltf) group.add(gltf.scene.getObjectByName('水壶')) group.getObjectByName('水壶').visible = false mixershuihu = new THREE.AnimationMixer(group.getObjectByName('水壶')) actionanimationshuihu = mixershuihu.clipAction(gltf.animations[0]) actionanimationshuihu.timeScale = 4 actionanimationshuihu.clampWhenFinished = false actionanimationshuihu.loop = THREE.LoopOnce c1 = new THREE.Clock() mixershuihu.addEventListener('finished', e => { group.getObjectByName('水壶').visible = false actionanimationshuihu.stop() scene.remove(groups) spriteflag = false })})const renderer = new THREE.WebGLRenderer({antialias: true})renderer.setSize(width, height)renderer.domElement.style.position = 'absolute'renderer.domElement.style.top = '0'renderer.domElement.style.left = '0'renderer.domElement.style.bottom = '0'renderer.domElement.style.right = '0'renderer.domElement.style.zIndex = '-1'let select = 0const btn = document.getElementById('add')btn.addEventListener('click', function () { if (select !== 2) { select++ } else { select = 0 } group.getObjectByName('水壶').visible = true actionanimationshuihu.play() groups.traverse(m => { m.position.y = Math.random() * spritey }) scene.add(groups) spriteflag = true})const control = new OrbitControls(camera, renderer.domElement);(function animation() { if (mixer && clock) { mixer.update(clock.getDelta()) if (select === 1) { actionAnimation.timeScale = 1 if (clock.getElapsedTime() >= 5) { actionAnimation.timeScale = 0 } } else if (select === 2) { actionAnimation.timeScale = 1 if (clock.getElapsedTime() >= 22) { actionAnimation.timeScale = 0 } } } if (mixershuihu && c1) { mixershuihu.update(c1.getDelta()) } if (spriteflag) { groups.traverse(m => { if (m.position.y >= 0.2) { m.position.y -= 0.02 } }) } renderer.render(scene, camera) requestAnimationFrame(animation)})();window.onresize = () => { camera.aspect = window.innerWidth / window.innerHeight camera.updateProjectionMatrix() renderer.setSize(window.innerWidth, window.innerHeight)}document.getElementById('data-three-js').appendChild(renderer.domElement)
四、效果图
项目搭建完毕,使用命令“npm run dev”运行。
点击浇水按钮,实现浇水后植物长大效果,效果图如下: