甜甜圈掉落效果(基于Threejs+Blender实现)| 大帅老猿threejs特训
前言
- 以前断断续续地通过大帅Threejs零度基点的直通来浅学Threejs,虽然没怎么花力气,但也学到了一些Threejs的技巧和api。
- 这门课主要讲的是Threejs的制作内容,在平时看过的几个3D项目中大量的动画和操作结合在一起,不由得感慨3D项目也太复杂了。
最近,大帅邀请胖达老师带来了元宇宙实战特训,具体介绍了如何用Blender进行3D建模、添加动画以及在Threejs中展示和控制3D模型,解答了我的疑问。 看起来很复杂的3D项目能这么容易实现吗? - 下面通过看看甜甜圈的盒子吧,看看threejs的安装和基础APP应用程序
分析需求
- 要实现动图的圆环效果,代码级思想要求利用threejs制作圆环,并改变其位置以实现动画效果。 看起来也不错,但其实要自己实现这个甜甜圈和动画效果太复杂了。 这不,胖达老师给我们带来了实战性的解决方案。
1、下载模型
- 可以去3D模型资源网站下载甜甜圈的模型,在Blender中详细处理模型,按照我们想要的形式处理。 因为以前接触过3DMAX,所以我觉得这部分的处理大部分相同,是虚线面的处理和材质贴图等。 除了构建模型外,Blender还可以向模型中添加逐帧动画,这样实现的模型引入Threejs后可以轻松实现动画。
2、代码实现
1、在npm上下载Threejs
npm i three
2、在项目中引用Threejs
import * as THREE from 'three';
3、创建场景、摄影机和渲染器,并将渲染器添加到dom
/*** 创建场景和相机以及渲染器的逻辑*/const scene = new THREE.Scene()const camera = new THREE.PerspectiveCamera(75,// 广角window.innerWidth / window.innerHeight,// 压缩比0.01,// 场景的近距离锥体10// 场景的远距离锥体)const renderer = new THREE.WebGLRenderer({ antialias: true // 抗锯齿(开启就会消耗更多得性能)})// 设置渲染器大小renderer.setSize(window.innerWidth,window.innerHeight)// 将渲染器添加到domdocument.body.appendChild(renderer.domElement)
4、创建环境光
/*** 创建环境光*/const ambientLight = new THREE.AmbientLight(0xffffff, 0.2);scene.add(ambientLight);
5、创建几何体并看一下场景构建是否成功
/*** 创建几何体 (用于测试)*/const boxGeometry =new THREE.BoxGeometry(1,1,1)const boxMaterial = new THREE.MeshBasicMaterial({color: 0xdedede})const boxMesh = new THREE.Mesh(boxGeometry,boxMaterial)scene.add(boxMesh)
6、创建关键帧动画,并渲染生成的场景和摄影机
/*** 创建关键帧动画*/
function animate () {requestAnimationFrame(animate)renderer.render(scene,camera)
}
animate()
7、这样就完成了基础场景,但此时看页面一片漆黑。 为了测试而制作的集合体也消失了。 实际上,摄影机的初始位置是( 0,0,0 )位于几何体内部,因此会偏移摄影机的位置
// 放置相机位置,要不然是在盒子里面,一片黑camera.position.set(0,0,2)
8、控制器控制相机的制作
import { OrbitControls } from "three/examples/jsm/controls/OrbitControls";
// ....
// 创建控制
const controls = new OrbitControls(camera,renderer.domElement)
function animate () {// ....controls.update()
}
9、添加hdr环境地图
/*** 添加hdr环境贴图*/
new RGBELoader().load('../resources/sky.hdr', function (texture) {scene.background = texture;texture.mapping = THREE.EquirectangularReflectionMapping;scene.environment = texture;renderer.outputEncoding = THREE.sRGBEncoding;renderer.render(scene, camera);});
10、添加三维模型
import { GLTFLoader } from "three/examples/jsm/loaders/GLTFLoader";
// ....
let donuts;
new GLTFLoader().load('../resources/models/donuts.glb', (gltf) => {console.log(gltf);scene.add(gltf.scene);donuts = gltf.scene;
})
这样就加载了我们的3D模型。
很简单吧?
但是,现在对甜甜圈也没有效果。 如何提高效果呢? 你可能会考虑一个一个地得到甜甜圈的对象,然后手工编写代码来提高效果。 然后,我们来考虑一下该如何获得甜甜圈的对象。
打印下面加载的模型,看看包含什么属性

您可以看到scene对象包含几个Mesh。
这些实际上是用Blender构建的各个模型,可以通过改变这些Mesh的位置来获得动画效果。
但是,我们还发现animations有六个AnimationClip。 实际上,这6个动画剪辑与在Blender中为6个圆环创建的动画相对应。 这六个动画剪辑包含六个甜甜圈的动画信息。 让我们看看下面的用法
let donuts;
let mixer;
new GLTFLoader().load('../resources/models/donuts.glb', (gltf) => {console.log(gltf);scene.add(gltf.scene);donuts = gltf.scene;
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 animate() {// ....if (mixer) {mixer.update(0.02);}
}
总结
这个案例虽然比较简单,但是可以知道程序开发和美术资源是如何合作的,可以学习3D模型在Threejs中是如何使用的,相信对打开Threejs的大门会有帮助。 当然,胖老师后面的课上谈到了更复杂的元宇宙场景如何实现,如何加载人物模型控制运动,更能引起大家的兴趣。 另外,有时间的话请分享。
最后
大家也可以直接公众号搜索
大帅老猿学习Threejs相关知识,也可以加入猿创营 (v:dashuailaoyuan),一起交流学习。`
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
