引言: 作为一名传统vue操作员,我将和你一起进入前端3D开发以及React的世界,为个人发展提供可能性(共同学习⛽)此项目可能需要你有一点点前置知识(React)。
学习目标:🔘
- ⭐了解3D开发的内部工作原理
- ⭐掌握Three.js基础知识
- ⭐为Web和移动应用程序创建优美的3D效果
- ⭐使用React Three Fiber 和 React Three Drei 开发应用程序
- ⭐使用GSAP探索动画
- ⭐使用Blender进行3D建模
(Section One) 什么是Three.js❓
👋Three.js 是一个功能强大的开源库,用于在Web上创建令人惊叹的3D视觉效果,它为开发人员提供了一组易于使用的[webgl](WebGL 概念和基础入门WebGL 是什么 对于 WebGL 百度百科给出的解释是 WebGL 是一种 3D 绘图协 - 掘金封装(webgl在此暂不做赘述,想要了解的小伙伴可以点击大佬的链接,我在后续的特效文章也会讲到。)用于构建可以在任何现代web浏览器中呈现的交互式动画3D图形。
💼借助Three.js 我们可以创建各种3D对象和场景,包括复杂的几何图形、动态粒子系统以及逼真的照明和阴影效果。无论您是构建游戏、数据可视化还是交互式产品演示,Three.js 都能提供将想法变为现实所需的灵活性和功能。Three.js 的主要优势之一是它与不同的 Web 技术和框架(包括 HTML5、CSS 和 JavaScript)的广泛兼容性。这意味着您可以轻松地将Three.js集成到现有的 Web 项目中,或者使用熟悉的 Web 开发工具和技术从头开始新项目。
❗最重要的是Three.js拥有充满活力的社区(基本上好像每周更新一次😅),不断发展和改进,无论您是经验丰富的 3D 程序员还是新手,它都为构建🐄B的交互式 Web 体验提供了充满创意的可能。
基础🦾
📺Renderer(渲染器)
- 渲染器负责将3D的场景绘制到Web页面上(实际上就是将Scene 场景 和 Camera相机 传递给Renderer渲染器,然后将相机视锥体内的3D场景部分进行投射成2D渲染到Canvas 画布上),在Three.js中,WebGlRenderer类用于创建渲染器。它使用WebGl(上文提过 一种基于OpenGL ES的图形API)与GPU交互并将场景绘制到网页上。
🌐Geometry(几何元素)
- 几何图形定义Three.js中一个对象的形状和结构,它由顶点(3D空间中的点)和面(链接顶点的三角面)组成。Three.js提供了许多内置的几何体,例如BoxGeometry(立方体),SphereGeometry(球体)和PlaneGeometry(平面),以及创建自定义集合体的功能。
🔦Light(光)
- 光是Three.js中能对你视觉造成冲击的大部分原因,有光线关系你才可以感知到物体的结构。它是用于模拟光线与场景中对象的交互方式。在 Three.js 中,灯光用于照亮场景并创建阴影。Three.js 提供了许多内置光源,例如 AmbientLight(环境光)、DirectionalLight(平行光) 和 PointLight(点光源),以及创建自定义光源的功能。
📸Camera(相机)
- 摄像机确定查看器在场景中的视角和位置。PerspectiveCamera(透视相机) 和 OrthographicCamera(正交相机) 类用于创建相机。PerspectiveCamera 模拟透视视图,而 OrthographicCamera 模拟等轴测视图
🏆Material(材质)
- 材质定义对象在场景中的显示方式,包括其颜色、纹理和阴影。这些材料被应用于几何体以定义其外观。它提供了许多内置材质,例如 MeshBasicMaterial(网格基础材质)、MeshLambertMaterial(网格Lambert材质- 受光照影响) 和 MeshPhongMaterial(网格Phone材质-受光照影响,可以实现镜面反射的效果,以及玻璃透明效果等),以及使用着色器创建,下图给大家简单列了一下不同材质的效果,想要自己试一下的可以点击此链接选一下不同材质和颜色玩一玩,还有一些不常用的材质在此不做赘述,后续用到再议。
🎬 Scene (场景)
- 场景就是容纳上述所有元素(元素,相机,灯光)的容器
🧱Texture (纹理)
- 纹理是应用于Three.js材质的图像。纹理可用于向对象的表面添加细节例如木纹图案或大理石纹理。在 Three.js 中,使用 TextureLoader 类加载纹理,并使用 texture 属性应用于材质。
🎞️Animation(动画)
- 动画实在3D场景中随时间闯将运动或更改的过程在Three.js中动画是使用requestAnimationFrame方法来实现更新对象的位置,旋转和缩放的。
了解完上述内容,其实你已经知道了Three.js的所有内容了,也可以来创建我们第一个3D场景了
(Section Two) 寻找“二次元”的你
step1🎯 捏人
-
此次Three.js之旅我们从寻找一个自己的模型开始,首先进入ReadyPlayerMe这个网站(可能有些人,比较慢这个只能去github上自己想一下办法了。。。😅,或者进入我的仓库,public文件夹下有准备好的素材🌟🌟🌟)
点击创建一个你自己的角色(这里需要准备一张你迷人的自拍照)
-
造型MakeUp一下,在我们的一阵骚操作下,哥们捏了个销售(bushi😅),然后我们就
可以点击Next去生成我们的人物模型
- 点击copy我们复制链接就可以把我们的模型下载下来啦,可以看到我们得到了一个glb文件,这也是我们前端最常用的模型文件格式。(到现在我们已经向web3D开发迈出了一大步了)
step2 🎯给模型附魔
- 🛞 转换
首先我们需要把glb的模型文件转换成可以绑定动画的FBX文件,我们需要下载一个强大的开源免费的建模工具([Blender](blender.org - Home of the Blender project - Free and Open 3D Creation Software)),然后打开软件,删除调默认的方块模型,相机,还有灯光,选中模型按X键或者Delete键就可以删除掉了
导入我们下载好的文件glb文件
导入以后先把这俩文件也删掉
然后我们就可以导出一个Fbx文件来绑定动画了!🎉🎉🎉
- 人物动画绑定
首先我们进入Mixamo这个网站,点击upload character 上传我们刚刚导出的FBX文件,然后选择一个左侧你喜欢的动作,我们把这个模型下载下来
Step3 🎯创建React项目
-
首先说一下我们为什么使用React 而不是Vue (俺其实很想用Vue),一个比较重要的原因是现阶段使用React-Three-fiber 以及React-Three-drei开发three.js很方便,并且社区已经非常完善了,对比vue 你差不多只可以使用three.js这个原生库去开发,虽然也有类似TroisJs Vue-GL 以及vue-Three这种库,但是和上面React的两个库相比还是小巫见大巫了,差的比较多,不过说到底,工具不重要,重要的是我们需要练习WEB3D开发的思维
第一步,我们需要创建一个React项目(如果可以我希望你可以跟我保持一样的node版本,我的node版本是20.15.1)
npm create vite@latest react_threejs -- --template react
npm i
npm run dev
下载依赖并启动项目,可以看到我们当前创建了一个React的前端模板框架
样式方面我们选择使用安装 - TailwindCSS中文文档 | TailwindCSS中文网,如果你不想使用tailwindcss可以跳过这部分,使用原生css,scss或less等,此系列tailwindcss不是课程的主要目的,本文也不会用到。
然后我们需要安装一些库
npm i three @react-three/fiber @react-three/drei
我们先编写一些代码来看一看想要实现一个简单的3D页面有多么方便
/* eslint-disable react/no-unknown-property */
import { Canvas } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
function App() {
return (
<Canvas
style={{
height: "100vh",
width: "100vw",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<OrbitControls enableZoom enablePan enableRotate />
<directionalLight/>
<mesh>
<boxGeometry />
<meshStandardMaterial />
</mesh>
</Canvas>
);
}
export default App;
🎉🎉🎉我们获得了一个立方体,并且我们可以拖动视角进行旋转,缩放!!
现在我们来逐行解析一下这些代码都代表了什么意思
- OrbitControls是一个来自 @react-three/drei 的控制器组件,用于控制相机视角
- Canvas 是创建 3D 场景的容器,样式设置使其占满整个视口(100vh/100vw)并居中内容
<OrbitControls enableZoom enablePan enableRotate />
- 添加轨道控制器,允许用户:
- 缩放(zoom)
- 平移(pan)
- 旋转(rotate
<directionalLight position={[10, 10, 10]} intensity={1} />
- 添加平行光源,位于坐标 [10,10,10],强度为 1
<mesh>
<boxGeometry />
<meshStandardMaterial />
</mesh>
- 创建一个基础的立方体:
- mesh 是 3D 对象的容器
- boxGeometry 定义立方体的形状
- meshStandardMaterial 定义材质
我要说明的是,react-three/fiber,react-three/drei这两个库基于的是threejs 如果你也用过three.js进行开发,你会发现这两个库简直太方便了,我们引入的Canvas组件承担了 threejs中 Scene 和Renderer的作用。Canvas 使用createRoot,创建一个WebGLRenderer,一个Perspective透视相机,Canvas的children属性可以接收 three.js jsx元素或者一些常规组件
相关代码
import * as THREE from 'three'
import { extend, createRoot, events } from '@react-three/fiber'
// 将THREE 命名空间注册为原生JSX元素
extend(THREE)
// 创建 react root
const root = createRoot(document.querySelector('canvas'))
// 配置 root、可选地注入事件、设置 camera 等
root.configure({ events, camera: { position: [0, 0, 50] } })
// 监听浏览器窗口大小变化,进行调整
window.addEventListener('resize', () => {
root.configure({ size: { width: window.innerWidth, height: window.innerHeight } })
})
// 触发窗口尺寸变化事件
window.dispatchEvent(new Event('resize'))
// 在入口进行渲染
root.render(<App />)
Step3 🎯 动起来吧,二次元
- 我们把下载好的模型放到public文件夹下
/* eslint-disable react/no-unknown-property */
import { Canvas } from "@react-three/fiber";
import { OrbitControls,useGLTF,useAnimations } from "@react-three/drei";
import { useEffect } from "react";
function Model(){
const {scene,animations} = useGLTF('model/Person.glb')
const {actions} = useAnimations(animations,scene)
useEffect(() => {
// 启动第一个动画(如果存在的话)
const firstAnimation = Object.values(actions)[0];
if (firstAnimation) {
firstAnimation.play();
}
}, [actions]);
return <primitive object={scene} />;
}
function App() {
return (
<Canvas
style={{
height: "100vh",
width: "100vw",
display: "flex",
justifyContent: "center",
alignItems: "center",
}}
>
<OrbitControls />
<ambientLight intensity={0.5} />
<directionalLight position={[5, 5, 5]} intensity={1} />
<Model />
</Canvas>
);
}
export default App;
如果你也出现了这个画面,恭喜你,成功点亮了threejs的"Hello World!"
我们来解释一下这些代码💼
- useGLTF: 用于加载 GLB/GLTF 格式的 3D 模型
- scene: 包含模型的场景对象
- animations: 模型包含的动画数据
- useEffect 在组件挂载后自动播放第一个动画
- 将 Three.js 对象直接渲染到场景中
- 光源设置:
- ambientLight: 环境光,提供整体照明
- directionalLight: 平行光,提供方向性的光照
- Model: 渲染我们的 3D 模型
小结:
- 本文简单介绍了ThreeJS的基础,(渲染器,相机,网格【Geometry,Material】灯光,相机等)
- 带大家简单下载模型以及绑定动画
- 介绍了RTF组件Canvas 以及模型的下载与导入,使用副作用函数对模型进行操作,在前端页面的显示等。
🧷🧷🧷最后附上本文的所有链接Mixamo ,Ready Player Me Studio
🧷🎉🎉🎉以及此项目的[github](GitHub - Benbende41/Travle-In-ThreeJS)链接,此项目应该会不断更新。这是我第一次发文,希望大家有所收获,欢迎讨论。