甜甜圈掉落效果(基于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)
    // 将渲染器添加到dom
    document.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模型。
很简单吧?

但是,现在对甜甜圈也没有效果。 如何提高效果呢? 你可能会考虑一个一个地得到甜甜圈的对象,然后手工编写代码来提高效果。 然后,我们来考虑一下该如何获得甜甜圈的对象。

打印下面加载的模型,看看包含什么属性

image.png

您可以看到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),一起交流学习。`

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值