乐趣区

关于前端:送你一个甜甜圈|大帅老猿threejs特训

写在后面,这是第一次发表技术类文章,2022 年原本给本人定了一个指标在掘金发表 10 篇 技术类的文章。后果反正因为各种各样的起因,导致最初也没有实现,甚至都没有开始。2022 年产出为 0。这一次实战课程起因是在群里看到胖达老师做了一单,那金额着实让我艳羡呀。而后就在千呼万唤中,胖达老师筹备出一个教程,率领大家入门之后并会出大教程,率领大家丰盛致富伎俩。

当然其实这次决定来写这个文章还有一个决定性的因素,群里的大佬天天打卡实现了文章,就比你厉害的大佬还比你勤奋,还在学习。就霎时感觉本人也要迈出这第一步的。就平时可能也是晓得大佬们都是很致力,然而其实我都没看到。这一次那属于天天都看到了,刺激的更显著。也谢谢群里的各位大佬们。

第一次写技术文章如果写的不好,或者怎么改良的,心愿路过的前辈们给予指导!!!

效果图

我看到第一反馈是上来就这个难度???这我只是一个 Three 的小白,上来就让我跑,不太适宜吧!当然可能可能只有我的反馈是这样的。当然毕竟是个程序员,不能被唬倒(工作中奇奇怪怪的需要也不是没有碰到过)。所以接下来咱们来剖析一下需要,来看下怎么实现这个成果。

剖析

首先这个动图,有几个货色,

  • 第一个背景这个应该是通过相似背景图的形式来加载进来的,所以这个应该不麻烦。
  • 第二个会转的盘子还是有花纹的,这个旋转应该 Three.js 外面有对应的 api 吧,花纹也是背景图吧。
  • 第三个那个装甜甜圈的盘子,还有 6 个甜甜圈,还各自都是主动掉落,这要怎么做呀

以上是我看到这个货色后,第一反馈

而后胖达老师在之后解说过程中说,首先咱们去 3D 模型网站(这里写网址)下载一个甜甜圈的模型。当然这个不能说找到十分合乎本人需要的模型图,这时候咱们下载一个本体,而后用 Blender 这个软件进行对模型的批改。来改成本人所须要应用的模型样子。解决好模型后,接下来就是咱们要搭建运行环境(Three.js 的装置能够参考官网的文档 放地址)那么接下来就来介绍一下怎么制作

开始

首先要有根底场景三大件

  • scene:场景 new THREE.Scene();
  • camera:相机 new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.01, 10)
  • renderer: 渲染器 new THREE.WebGLRenderer()

三大件都有了之后那么就要给 renderer 渲染器设置一下大小,而后把渲染器增加到页面里,再来设置一下相机的地位。这是咱们创立一个盒子模型。放进场景,开启祯循环在当中把场景和相机初始化进去。这时候咱们来看下成果,就是会呈现一个绿色的方块能够依据咱们的鼠标随便进行旋转、放大放大。能够管制物体。

案例代码

这时候还是在乌黑的夜里,咱们加载一下环境光 HDR 图片:RGBELoader

是不是当初一下子就感觉对了,成果也和最开始的差不多,环境有了,当初就是把咱们创立的盒子换成甜甜圈模式就实现了成果了,话不多说,马上来加载甜甜圈模型。当当当,最初的成果就进去了。

END


集体踩坑

  • 首先是类型问题,three 没有像 TS 那样如果类型错了,就给你报错,在控制台也很失常也没爆红,不像咱们平时写业务代码,如果代码上有问题,控制台是间接报错,会给你谬误提醒,three 只能你本人进行排查,你在后面都能够,忽然在这里不行了,或者你在本地测试都能够,和后端联调时,忽然发现自己的成果变没了,这时候能够看下是不是接口返回的数据类型谬误。
  • 因为 Three.js 是 3D 的,所以有时候一开始咱们还不纯熟的时候,相机地位常常没有放对,而后你的代码都没有写错,然而看成果的时候,间接看不到货色,这时候你会蒙了,什么状况,我是不是不适宜学这个之类的想法,你能够鼠标滚轮放大放大看看,成果能不能处来,是成果自身的确有问题,还是你的相机初始地位的问题。
  • Three.js 是慢工出细活,可能大家都是用了同样的 API,同样的代码,然而人家在那边调了许久的参数,进去的成果可能就是很难看,或者说很实在。这个也没捷径,只能是缓缓调。当然可能有只是我不晓得。

结语

终于写完了本人第一篇的技术文章,开始了第一步,先给本人鼓个掌。这一篇只是略微介绍了 Three.js 根本的 API,以及做了一个小 demo。前面打算在写一篇,从 Blender 软件中建模开始,建设一个根底模型,而后安排一下。找个人物。让这个人物能够在场馆里游历。一个元宇宙的雏形,因为波及建模的操作,所以打算会录制一个视频放在 B 站,仅供参考,毕竟我也是老手。(原本是想写在一篇的,然而感觉篇幅太长,看的累,其次我也有公心,怕本人第一篇写完又停下了,没有写,所以还是多写下,让本人习惯写文章的习惯)。

游刃有余,你学会了,不代表你了解了,当你用你的语言说进去,让其他人听懂了,这才是阐明你真的把握这个常识、技能了。

能够间接上 B 站搜寻 Web3D 胖达 有三天打卡营的直播回放视频,当然比我这个讲的粗疏,讲的好了。

当然最初还是要谢谢大帅老师(晓得于开课吧的前端全栈课程)和胖达老师(晓得于群里发放收益时),不止教了常识,还让我迈出了写文章的第一步,心愿 2023 年,能够实现发 10 篇技术文章的 fiag。欢送退出猿创营 (v:dashuailaoyuan),一起交流学习。

案例代码

import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls';
import {GLTFLoader} from 'three/examples/jsm/loaders/GLTFLoader';
import {RGBELoader} from 'three/examples/jsm/loaders/RGBELoader';

let mixer;

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);
document.body.appendChild(renderer.domElement);

camera.position.set(0.5, 0.4, 0.7);

const controls = new OrbitControls(camera, renderer.domElement);

// 创立环境光,有光了才亮了
const ambientLight = new THREE.AmbientLight(0xffffff, 0.3);
scene.add(ambientLight);

const directionLight = new THREE.DirectionalLight(0xffffff, 0.4);
scene.add(directionLight);

let donuts;
new GLTFLoader().load('../resources/models/donuts.glb', (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();});
});

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);
});

/*
* 祯循环
*/
animate();
function animate() {requestAnimationFrame(animate);
    renderer.render(scene, camera);
    controls.update();
    if (donuts) {donuts.rotation.y += 0.01;}
    if (mixer) {mixer.update(0.02);
    }
}
退出移动版