使用 react-three-fiber 深入 React 和 Three.js
已发表: 2022-03-10react-three-fiber
是一个强大的 Three.js 渲染器,可以帮助渲染 React 及其原生应用程序的 3D 模型和动画。 在本教程中,您将学习如何在 React 应用程序中配置和构建 3D 模型。 今天,我们将学习如何配置和使用react-three-fiber
在 React 和 React Native 应用程序中构建和显示 3D 模型和动画。
本教程适用于想要了解更多关于使用 React 的 Web 中的 3D 模型动画的开发人员,以及任何对 Three.js 有限制(例如无法创建画布、绑定用户事件(如click
事件)和启动渲染循环、 react-three-fiber
)的人react-three-fiber
带有这些方法。 我们将构建一个 3D 模型,以更好地了解如何使用react-three-fiber
构建 Three.js 3D 模型。
react-three-fiber
入门
Three.js 是一个可以更轻松地在浏览器中创建 3D 图形的库,它使用画布 + WebGL 来显示 3D 模型和动画,您可以在此处了解更多信息。
react-three-fiber 是 web 上 Three.js 和 react-native 的 React 渲染器,它提高了使用 Three.js 创建 3D 模型和动画的速度,一些具有 3D 模型和动画的网站示例可以在这里找到。 react-three-fiber
减少了在动画上花费的时间,因为它具有可重用的组件、绑定事件和渲染循环,首先我们来看看 Three.js 是什么。
react-three-fiber
允许我们使用 React 状态、钩子和道具构建threeJS
代码的组件,它还带有以下元素:
元素 | 描述 |
---|---|
mesh | 有助于定义模型形状的属性 |
hooks | react-three-fiber 定义了帮助我们编写函数来帮助定义用户事件的钩子,例如onClick 和onPointOver |
基于组件和渲染循环 | react-three-fiber 是基于组件的,根据状态或存储的变化进行渲染 |
如何使用react-three-fiber
要使用react-three-fiber
,首先使用以下命令:
新PM
npm i three react-three-fiber
纱
yarn add three react-three-fiber
注意:要让react-three-fiber
工作,你需要像我们上面那样安装three
(Three.js)。
构建 React 3D Ludo Dice 模型和动画项目
在这里,我们将使用react-three-fiber
构建一个 3D 骰子模型,就像我们在下面的视频中一样。
我们将使用create-react-app
来初始化我们的项目,为此让我们在终端上执行以下命令。
create-react-app react-three-fiber-ludo-model
上面的命令在我们的本地机器中初始化了一个 React 项目,接下来让我们cd
进入目录并安装我们的包react-three-fiber
和three
。
cd react-three-fiber-ludo-model npm i three react-three-fiber
一旦安装了软件包,让我们使用命令启动我们的开发服务器
npm start
上面的命令应该在我们的浏览器中启动我们的项目开发服务器。 接下来让我们在我们选择的文本编辑器中打开我们的项目,在我们的项目src
文件夹中,删除以下文件: App.css
、 App.test.js
、 serviceWorker.js
和setupTests.js
。 接下来,让我们删除所有引用App.js
上已删除文件的代码。
对于这个项目,我们将需要一个Box
组件用于我们的 Ludo 骰子和由 React 提供的App
组件。
构建Box
组件
Box
组件将包含我们的ludo 骰子的形状、ludo 骰子的图像和始终保持旋转的状态。 首先,让我们为下面的Box
组件导入我们需要的所有包。
import React, { useRef, useState, useMemo } from "react"; import { Canvas, useFrame } from "react-three-fiber"; import * as THREE from "three"; import five from "./assets/five.png";
在上面的代码中,我们导入useRef
、 useState
和useMemo
。 我们将使用useRef
钩子来访问骰子的网格,并使用useState
钩子来检查 ludo 骰子的活动状态。 useMemo
钩子将用于返回骰子上的数字。 接下来,我们从react-three-fiber
导入Canvas
和useFrame
, canvas
用于在浏览器上绘制图形,而useFrame
允许组件挂钩到渲染循环,这使得一个组件可以渲染另一个的内容。 接下来,我们导入了这three
包,然后我们导入了一个卢多骰子的静态图像。
接下来是为我们的Box
组件编写逻辑。 首先,我们将从构建一个功能组件开始,并为我们的组件添加状态,让我们在下面这样做。
const Box = (props) => { const mesh = useRef(); const [active, setActive] = useState(false); useFrame(() => { mesh.current.rotation.x = mesh.current.rotation.y += 0.01; }); const texture = useMemo(() => new THREE.TextureLoader().load(five), []); return ( <Box /> ); }
在上面的代码中,我们创建了一个带有 props 的Box
组件,接下来我们使用useRef
钩子创建了一个名为mesh
的引用,这样做是为了每次都可以返回相同的网格。
网格是场景中的视觉元素,它是构成三角形多边形的 3D 对象,它通常使用Geometry构建,用于定义模型的形状, Material用于定义模型的外观,您可以在此处了解 Mesh,您还可以在此处了解有关useRef
挂钩的更多信息。

初始化mesh
后,我们需要使用useState
钩子为我们的应用程序初始化一个状态,这里我们将应用程序的悬停和活动状态设置为 false。
接下来,我们使用react-three-fiber
中的useFrame
钩子来旋转网格(ludo dice),使用下面的代码
mesh.current.rotation.x = mesh.current.rotation.y += 0.01;
在这里,我们每 0.01 秒旋转一次网格的当前位置,这样做是为了给旋转一个好的动画。
const texture = useMemo(() => new THREE.TextureLoader().load(five), []);
在上面的代码中,我们创建了一个名为texture
的常量,并传入一个 react useMemo
钩子作为函数来加载一个新的掷骰子,这里使用useMemo
来记忆骰子图像及其编号。 你可以在这里了解useMemo
钩子。
接下来,我们要在浏览器上渲染Box
组件并添加我们的事件,我们在下面这样做
const Box = (props) => { return ( <mesh {...props} ref={mesh} scale={active ? [2, 2, 2] : [1.5, 1.5, 1.5]} onClick={(e) => setActive(!active)} > <boxBufferGeometry args={[1, 1, 1]} /> <meshBasicMaterial attach="material" transparent side={THREE.DoubleSide}> <primitive attach="map" object={texture} /> </meshBasicMaterial> </mesh> ); }
在上面的代码中,我们返回了我们的Box
组件并将其包装在mesh
中,我们使用扩展运算符传递了Box
组件的所有属性,然后我们使用useRef
挂钩引用了网格。 接下来,我们使用 Three.js 中的scale
属性来设置骰子框的大小,当它处于活动状态时为 2 和 1.5,当它不处于活动状态时。 最后但并非最不重要的一点是,我们添加了一个onClick
事件以将state
设置为active
,如果它未设置为默认值。
<boxBufferGeometry args={[1, 1, 1]} />
为了渲染骰子盒子,我们从 Three.js 中渲染了boxBufferGeometry
组件, boxBufferGeometry
帮助我们绘制了诸如盒子之类的线和点,我们使用args
参数来传递诸如盒子几何尺寸之类的构造函数。
<meshBasicMaterial attach="material" transparent side={THREE.DoubleSide}>
meshBasicMaterial
中的 meshBasicMaterial 用于以简单的形式绘制几何图形。 在这里,我们传递了attach
属性并将THREE.DoubleSide
道具传递给side
属性。 THREE.DoubleSide
定义了应该由react-three-fiber
渲染的边或空间。
<primitive attach="map" object={texture} />
Three.js 的primitive
组件用于绘制 3D 图形。 我们附加了 map 属性以保持 Ludo 骰子的原始形状。 接下来,我们将在App.js
文件中渲染我们的Box
组件并完成我们的 3d ludo 骰子框。 您的组件应该类似于下图。

渲染 3D Ludo 骰子盒
在本节中,我们将在App.js
中渲染我们的Box
组件并完成我们的 3d ludo 框,首先,让我们创建一个App
组件并用Canvas
标签包装它,这是为了渲染我们的 3D 模型,让我们在下面这样做。
const App = () => { return ( <Canvas> </Canvas> ); } export default App;
接下来,让我们为盒子添加一个灯光, react-three-fiber
为我们提供了三个组件来点亮我们的模型,它们如下
ambientLight
这用于均匀地照亮场景或模型中的所有对象,它接受诸如光强度之类的道具,这将照亮卢多骰子的主体。-
spotLight
这种光是从一个方向发出的,它随着物体大小的增加而增加,这将照亮卢多骰子的点。 -
pointLight
这类似于灯泡的光,光从一个点发射到各个方向,这对于我们的应用程序的活动状态是必要的。
让我们在下面的应用程序中实现上述内容。
const App = () => { return ( <Canvas> <ambientLight intensity={0.5} /> <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} /> <pointLight position={[-10, -10, -10]} /> </Canvas> ); } export default App;
在上面的代码中,我们从react-three-fiber
导入了环境光组件,并pointLight
添加了 0.5 的强度,接下来我们为我们的spotLight
和ambientLight
组件添加了位置和角度。 我们应用程序的最后一步是渲染我们的盒子组件并为 ludo 骰子盒子添加一个位置,我们将在下面的代码中这样做
<Box position={[-1.2, 0, 0]} /> <Box position={[2.5, 0, 0]} />
完成后,您的 Ludo 3D 骰子应类似于下图:

CodeSandbox 上提供了一个工作演示。
结论
react-three-fiber
使得渲染 3D 模型和动画更容易为 React 和 React Native 应用程序创建。 通过构建我们的 3D 骰子盒,我们了解了 Three.js 的基础知识以及react-three-fiber
的组件和优点以及如何使用它。
您可以通过自己使用react-three-fiber
在您的 React 和 Native 应用程序中构建 3D 模型和动画来进一步实现这一点。 我很想看看你想出了什么新东西!
您可以在下面的参考资料中阅读有关 Three.js 和react-three-fiber
的更多信息。
相关资源
- 三.js 文档
- 三.js 基础
- Poimandres 的 React-Three-Fiber GitHub 存储库
- 反应三纤维文档
- React Hooks(useState、useMemo等)官方文档