使用 react-three-fiber 深入 React 和 Three.js

已发表: 2022-03-10
快速总结 ↬ react-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定义了帮助我们编写函数来帮助定义用户事件的钩子,例如onClickonPointOver
基于组件和渲染循环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-fiberthree

 cd react-three-fiber-ludo-model npm i three react-three-fiber

一旦安装了软件包,让我们使用命令启动我们的开发服务器

npm start

上面的命令应该在我们的浏览器中启动我们的项目开发服务器。 接下来让我们在我们选择的文本编辑器中打开我们的项目,在我们的项目src文件夹中,删除以下文件: App.cssApp.test.jsserviceWorker.jssetupTests.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";

在上面的代码中,我们导入useRefuseStateuseMemo 。 我们将使用useRef钩子来访问骰子的网格,并使用useState钩子来检查 ludo 骰子的活动状态。 useMemo钩子将用于返回骰子上的数字。 接下来,我们从react-three-fiber导入CanvasuseFramecanvas用于在浏览器上绘制图形,而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 骰子框。 您的组件应该类似于下图。

ludo 3D 盒子的盒子组件

渲染 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 的强度,接下来我们为我们的spotLightambientLight组件添加了位置和角度。 我们应用程序的最后一步是渲染我们的盒子组件并为 ludo 骰子盒子添加一个位置,我们将在下面的代码中这样做

<Box position={[-1.2, 0, 0]} /> <Box position={[2.5, 0, 0]} />

完成后,您的 Ludo 3D 骰子应类似于下图:

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等)官方文档