theme: scrolls-light
highlight: atom-one-dark
本文正在参加「金石计划 . 瓜分6万现金大奖」
Demo地址:r3f-demo
在之前的几篇的文章中,我们介绍了一些Three.js的基本用法:
假设现在你已经学会了所有的Three.js基本使用方法,已经能够创建简单场景,在场景中添加动画,灯光,阴影等,但是我们想在工程项目中集成Three.js,我推荐@react-three/fiber和@react-three/drei。这个是业界在React工程项目中使用Three.js比较成熟的解决方案。
react-three-fiber is a React renderer for threejs.
react-three-drei is a growing collection of useful helpers and fully functional, ready-made abstractions for @react-three/fiber.
今天这篇文章就带大家学习使用它们,你会发现,oh,amazing!
项目目录结构:
1. 使用r3f创建场景
// App.js
import { Canvas } from "@react-three/fiber";
export default function App() {
return (
<Wrapper className="App">
<Canvas className="canvas">
</Canvas>
</Wrapper>
);
}
2. 在场景中创建正方体
// ./components/Box.js
import React from "react";
export default function Box() {
return (
<mesh>
<boxBufferGeometry attach="geometry" />
<MeshLambertMaterial attach="material" />
</mesh>
);
}
// App.js
import Box from "./components/Box";
import { Canvas } from "@react-three/fiber";
export default function App() {
return (
<Wrapper className="App">
<Canvas className="canvas">
<Box />
</Canvas>
</Wrapper>
);
}
现在我们就成功地在场景中添加了正方体,但是它非常小,并且是黑色的,我们需要做出一些调整。
首先我们的canvas高度比较小,我们调整一下它的高度
canvas {
height: 500px;
}
如何更改正方体的大小?
我们只需要在boxBufferGeometry
添加args
属性即可,args
的属性值是一个数组,我们填入[3,3,3]
即将正方体的长宽高设置为3。
<mesh>
<boxBufferGeometry attach="geometry" args={[3, 3, 3]}/>
<meshNormalMaterial attach="material" />
</mesh>
现在看起来可能更像正方形,我们尝试给正方体添加一些旋转角度。在mesh
上添加rotation={[90, 0, 20]
即可
<mesh rotation={[90, 0, 20]}>
<boxBufferGeometry attach="geometry" args={[3, 3, 3]}/>
<MeshLambertMaterial attach="material" />
</mesh>
现在我们得到了一个全黑的正方体,接下来,尝试在场景中添加一些灯光。
如何添加灯光?
灯光元素应该添加canvas元素内
<Canvas className="canvas">
<ambientLight intensity={0.5} />
<directionalLight position={[-2, 5, 2]} intensity={1} />
</Canvas>
position
属性为光源的位置,intensity
属性为光源的强度
现在我们可以清楚看到正方体的每一个边缘了。
我们还需要添加轨道控制器,接下来,我们尝试添加它,这时候我们需要从@react-three/drei
中引入它。
然后在canvas
元素中添加它,其中enableZoom
属性的作用是控制是否可以缩放。
import { OrbitControls } from "@react-three/drei";
<Canvas className="canvas">
<OrbitControls enableZoom={false} />
<ambientLight intensity={0.5} />
<directionalLight position={[-2, 5, 2]} intensity={1} />
</Canvas>
接下来我们尝试在正方体上添加纹理。
如何给正方体添加纹理?
我们需要使用r3f
提供的一个加载器hook——useLoader
这里要注意,我们需要将mesh
的material
调整一下,将其调整为meshStandardMaterial
import React from "react";
import { useLoader } from "@react-three/fiber";
import { TextureLoader } from "three/src/loaders/TextureLoader";
import texture from "../images/map.jpg";
export default function Box() {
const colorMap = useLoader(TextureLoader, texture);
return (
<mesh rotation={[90, 0, 20]}>
<boxBufferGeometry attach="geometry" args={[3, 3, 3]} />
<meshStandardMaterial attach="material" />
</mesh>
);
}
这时候,你会发现有报错
提示你需要添加一个Suspense
,这是因为我们使用useLoader
时,无法获取到material
,然后就会报错,现在我们添加Suspense
// App.js
import React, { Suspense } from "react";
import Box from "./components/Box";
import { Canvas } from "@react-three/fiber";
export default function App() {
return (
<Wrapper className="App">
<Canvas className="canvas">
<OrbitControls enableZoom={false} />
<ambientLight intensity={0.5} />
<directionalLight position={[-2, 5, 2]} intensity={1} />
<Suspense fallback={null}>
<Box />
</Suspense>
</Canvas>
</Wrapper>
);
}
现在就成功地将纹理添加到正方体上了。
3. 在场景中导入3D模型
这次我们选择在Sketchfab上去找模型
我们挑一条鲨鱼啊,然后下载模型,当然我们应该选择gltf
格式,因为它对网站性能很好,不会减慢你的网站速度。
下载之后,我们需要借助gltf-pipeline将glTF 1.0 models 转换为 glTF 2.0
执行下面两个命令:
npm install -g gltf-pipeline
gltf-pipeline -i scene.gltf -o shark.gltf
现在我们得到了shark.gltf
文件,我们现在需要使用gltfjsx这个库,将我们的gltf
文件转换为jsx component
。
执行下面的命令:
npx gltfjsx shark.gltf
我这里执行命令,失败了
提示在node中Fetch
是一个实验性的功能,由于我的node用的是19.0.0,我们这里需要降级,这里降到14.17.6,然后继续执行上述命令即可
现在我们得到了shark.js
接着我们在App.js中引入即可
import React, { Suspense } from "react";
import "./styles.css";
import styled from "styled-components";
import Box from "./components/Box";
import Shark from "./components/Shark";
import { Canvas } from "@react-three/fiber";
import { OrbitControls } from "@react-three/drei";
export default function App() {
return (
<Wrapper className="App">
<Canvas className="canvas">
<OrbitControls enableZoom={false} />
<ambientLight intensity={0.5} />
<directionalLight position={[-2, 5, 2]} intensity={1} />
<Suspense fallback={null}>
<Box />
</Suspense>
</Canvas>
<Canvas className="canvas">
<OrbitControls enableZoom={false} />
<ambientLight intensity={0.5} />
<directionalLight position={[-2, 5, 2]} intensity={1} />
<Suspense fallback={null}>
<Shark />
</Suspense>
</Canvas>
</Wrapper>
);
}
现在就成功导入我们big shark啦,关于R3F的更多细节可参考
- https://github.com/pmndrs/react-three-fiber#Ecosystem
最后
⚾如果你对本专栏感兴趣欢迎点赞关注+收藏,后面会持续更新,更多精彩知识正在等你!😘
🏉此外笔者还有其他专栏,欢迎阅读~
🏐玩转CSS之美
🎳深入浅出JavaScript
暂无评论内容