如果你对 3D 图形的可能性着迷,但发现从头开始创建 3D 模型的想法是不可能的 - 不用担心!
Three.js 是一个强大的 JavaScript 库,它可以帮助我们轻松地将现有的 3D 模型集成到 React 应用程序中。因此,在本文中,我将深入探讨 Three.js 的基本知识,并指导你在项目中融入令人惊叹的 3D 模型。
NSDT工具推荐 : Three.js AI纹理开发包 - YOLO合成数据生成器 - GLTF/GLB在线编辑 - 3D模型格式在线转换 - 可编程3D场景编辑器 - REVIT导出3D模型插件 - 3D模型语义搜索引擎 - Three.js虚拟轴心开发包 - 3D模型在线减面 - STL模型在线切割
1、一切是如何开始的
曾几何时...
"在数字深渊的霓虹灯浸透的深处,一切都开始了。一行代码,电线中的一阵电流声,世界就被永远改变了。阴影里藏着秘密,在它们的内部,一个 他们说,这一切是如何开始的,是黑暗的、合成的未来,是由一次黑客攻击、一次突破、一次在电路中回响的下载引发了一场由 1 和 0 组成的革命。"
最近,我发现自己正在检查我的旧作品集,它迫切需要改造,因为它是在我刚刚开始编程时制作的。 我们可以忽略它的视觉细节。 👀
在设计方面,我知道我想要一些更真实的东西,而且由于我喜欢视频游戏,所以我渴望加入一些很酷的 3D 模型。
但问题是 - 我对 Three.js 的了解为零到很少,并且不想要无聊的球体或立方体。
因此,我卷起袖子,开始研究,很快我就找到了我的 3D 模型,并决定无论如何都要坚持将该 3D 模型纳入我的作品集!
该模型是 Oscar Creativo的杰作,这是他在 Sketchfab 上的个人资料。 我强烈建议你检查一下!
由于我花了相当多的时间寻找解决方案,然后结合了一些最佳实践和优化,并且因为我知道还有更多像我一样固执的人,所以我决定让他们的生活更轻松,并分享我的经验和实现目标的步骤 相同的结果。
我的目标是通过提供简单明了的解释来简化整个过程,并使其对初学者友好。
那么让我们开始吧!
2、关于 Three.js 和先决条件
虽然 Three.js 提供了一个广泛的工具包来从头开始构建 3D 体验,但我的重点将是利用可供开发人员使用的巨大的预制 3D 模型存储库。 为什么?
因为通过这样做,我们可以立即升级我们的 React 应用程序并引入一些真正令人印象深刻的东西。
尽管如此,在做出决定之前权衡利弊还是很重要的。 虽然利用预制 3D 模型具有明显的优势,例如节省时间、高质量、广泛的选择、潜在的成本节省和更快的学习曲线,但我们也必须考虑到一些缺点,例如定制有限、可能超载、许可限制 ,以及可能需要仔细考虑和适应的无缝集成的潜在挑战。
我的建议是探索可用的免费 3D 模型,并确保检查并包含适当的许可信息。 或者,考虑选择符合你偏好的付费模式。
现在,让我们做好准备,为你的应用程序注入活力!
先决条件如下:
2.1 很棒的3D模型🤩
有什么新鲜事吗,chromehead?
选择 3D 模型后,继续下载。 将出现以下对话框:
正如您将看到的,存在不同的格式,虽然 Three.js 可以处理所有这些格式,但 GLTF 或 GLB 是首选,因为它们的效率、多功能性以及 Three.js 社区和更广泛的 Web 开发生态系统中的广泛支持。
以下是几种格式的简短解释:
- FBX (Filmbox):电影和娱乐行业使用的流行专有 3D 模型格式,以其多功能性以及对动画和复杂场景的支持而闻名。 Three.js可以通过FBXLoader处理FBX模型。 它可以加载几何图形、动画和材质,适合导入电影和娱乐行业常用的复杂 3D 模型。
- USDZ(通用场景描述):针对在 iOS 设备上共享 3D 模型和 AR 体验而优化的文件格式,与 Apple 的 ARKit 良好集成。 USDZ 主要用于 iOS 设备上的 AR 应用程序。 虽然 Three.js 可以处理这些模型,但可能需要额外的步骤或转换才能将它们有效地集成到基于 Three.js 的项目中。
- GLTF(GL 传输格式):开放标准文件格式,可有效表示 3D 模型和场景,同时针对 Web 进行优化,使其成为基于 Web 的 3D 体验的广泛使用的格式。 由于其效率和对 Web 的适用性,GLTF 是 Three.js 的首选格式。 Three.js 有一个内置的 GLTFLoader,可以无缝加载 GLTF 模型,包括几何图形、材质、动画等。
GLB(GL Binary):基于 GLTF 的二进制文件格式,将 3D 场景、纹理和动画打包到单个文件中,提高效率和可移植性。 GLB 是 GLTF 的二进制版本,Three.js 可以使用相同的 GLTFLoader 来处理它。 GLB 文件是独立的,封装了 3D 模型及其关联数据,使其高效且易于使用。
由于上述原因,在本文中我将使用 GLTF 格式。 这些文件将以 zip 存档的形式下载,之后你需要将其解压缩。
3.2 React和three.js技术栈
我们需要安装以下库:
npm install three @react-three/drei @react-three/fiber
yarn add three @react-three/drei @react-three/fiber
- Three.js:一个强大的 JavaScript 库,用于创建和使用 3D 图形和模型。
- @react-two/drei:有用的钩子、组件和实用程序的集合,用于增强 Three.js 和 React 集成。
- @react-two/fibre:Three.js 的 React 渲染器,允许将 Three.js 无缝集成到 React 应用程序中。
4、关于文件夹结构和文件⚙️
public -> 3DfolderName
解压后的 3D 模型文件夹位于包含纹理文件夹以及 scene.bin、scene.gltf 和许可证的公共文件夹中。 请注意,每种格式都有不同的文件和结构。
src -> components (containing Loader.jsx) -> canvas folder -> CyberGirl.jsx + index.js
包含代码 CyberGirl.jsx 的主要组件放置在 canvas 文件夹中,并导出到 index.js 中,以便将来可扩展。 Loader.jsx 用作后备组件,用于显示 3D 模型的加载百分比。
5、代码及解释
CyberGirl.jsx:
useGLTF
钩子用于从指定路径加载 3D 模型。 它获取并准备 3D 模型以在 Three.js 环境中进行渲染。
useRef()
创建一个名为 modelRef
的 React 引用。 React 中的 Refs 用于直接访问 DOM 或 React 元素并与之交互。 它用于引用组件内的 3D 模型并应用转换或与其交互。
细节层次 (LOD) 是 Three.js 库中的一项功能,用于优化 3D 模型的渲染。 首先创建 LOD 类的实例来管理模型的不同版本。 在这种情况下,将创建原始 3D 模型的四个克隆实例,每个实例代表不同的细节级别。 此 LOD 通过在距离相机较远时显示简化模型来提高渲染性能,从而减少计算负载。
LOD 系统的运行独立于变焦或相机控制设置。 它旨在根据相机与模型之间的距离自动在不同版本的 3D 模型之间切换,无论是否启用缩放。
LOD 主要用于在不需要远距离渲染高细节模型且计算成本较高的场景下优化 3D 模型的渲染。 当相机靠近或远离模型时,LOD 系统会自动切换到适当的细节级别。
<primitive/>
是 Three.js 元素,用于渲染 3D 模型。 它使用 gltf.scene 作为模型/对象来显示并设置模型在 3D 空间中的比例、位置和旋转。 位置和旋转都使用具有三个值 [ X, Y, Z ]
的数组,表示沿 X、Y 和 Z 轴的坐标。 使用参考 (modelRef) 可以与渲染的 3D 模型进行潜在的编程交互。
Canvas
组件设置阴影和基于需求的帧循环,以及针对不同显示器的 1 和 2 的设备像素比。
shadows
是启用或禁用 3D 场景中阴影渲染的属性。 它表示场景将支持阴影渲染,这意味着 3D 对象可以投射和接收来自光源的阴影,从而为场景增添真实感。frameloop
是一个属性,决定如何在 3D 场景中管理动画循环。 在本例中,它设置为"需求"。 这意味着动画循环仅在明确请求时才会运行,通常是在需要设置动画时。 这可以更有效,因为它不会连续运行动画循环,从而可以节省计算资源。 帧循环的其他选项始终是 rAF (requestAnimationFrame)、调整大小和自定义函数。dpr
(设备像素比)是控制设备像素比的属性。 它被设置为数组 [1, 2],这意味着它为不同的显示器提供不同的像素比。 设备像素比用于确保图形在不同屏幕密度的设备(例如标准和高密度显示器)上清晰显示。 值 1 表示标准像素密度,值 2 表示高密度(视网膜)显示,需要以更高分辨率进行渲染才能清晰。
Suspense
将 CanvasLoader
组件渲染为后备,并在加载 3D 模型时显示加载进度指示器。
ambientLight
是一种光源,它均匀地照亮场景中的所有对象,无论其位置或方向如何。 它通常用于为整个场景提供基本级别的光线,模拟全局照明。 环境光不会投射阴影或具有特定方向,相反,它只是照亮一切。 有关道具的更多信息请查阅这里。
pointLight
是一种更具方向性的光源,从 3D 空间中的特定点向各个方向发射光。 它模拟点光源,如灯泡。 它可以投射阴影并具有各种属性,例如位置、颜色和强度。 位置指定灯光的位置,而颜色和强度分别控制灯光的颜色和亮度。 点光源对于创建局部的、真实的光照效果非常有用。 有关道具的更多信息,请检查此。
OrbitControls
组件允许在 3D 场景中进行交互式摄像机控制。 它使用户能够平移、缩放和绕 3D 对象旋转。
enableZoom
是指使用鼠标或触摸板进行放大和缩小的可能性。enablePan
指的是在场景内横向移动摄像机的可能性。 要使用此功能,请删除将 3D 模型固定在某个位置的 maxPolarAngle 和 minPolarAngle。autoRotate
通常使相机围绕某个兴趣点缓慢旋转。 将其设置为 false 会停止此行为。maxPolarAngle
和minPolarAngle
属性设置相机可以向上或向下倾斜的最大和最小角度(以弧度为单位)。 在这种情况下,其设置方式使得相机不能直视向上或向下。
要查找用于配置 OrbitControls 组件的可用属性的完整列表,请参阅此资源。
Preload
组件用于在渲染 3D 场景之前预加载资源。 具体来说,它用于异步预加载纹理、模型或其他资源,确保它们在场景开始渲染之前完全加载并可用。 它应该放置在 Suspense
组件中,以便在预加载资源时提供后备 UI。
Loader.jsx
CanvasLoader
组件的目标是在 3D 模型加载之前显示加载元素。 它从 @react-two/drei
库导入两个元素:Html 和 useProgress,以跟踪 3D 资源的加载进度。
加载进度以百分比形式显示在嵌套在居中的 Html 元素内的 p 中。 由于进度常量保存有几个小数位的浮点数,因此使用 toFixed(2)
将确保它在最终输出中显示为精确两位小数。
index.js
该文件充当 CyberGirl 组件的中心导出点,使得从应用程序的其他部分导入更加方便。 这种做法使导入语句保持干净和有组织,并且可以轻松扩展以包含其他 3D 组件。
Hero.jsx - 使用 3D 模型的地方
最后,从canvas文件夹中的index.js文件导入 CyberGirl
组件。
虽然还有更多选项可供探索和自定义,但此示例是使用 Three.js 集成令人印象深刻的预制 3D 模型的简单方法。 源代码可以在我的 GitHub上找到。
6、结束语
Three.js 和 React 的结合开启了一个充满创意可能性的世界,使我们能够将迷人的 3D 模型无缝集成到我们的 Web 应用程序中。 凭借大量可用的预制 3D 模型以及 react-three/fiber
和 react-three/drei
等库提供的简化 React 集成,为我们的应用程序注入活力是如此酷且轻松!