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的更多细节可参考
最后
⚾如果你对本专栏感兴趣欢迎点赞关注+收藏,后面会持续更新,更多精彩知识正在等你!😘
🏉此外笔者还有其他专栏,欢迎阅读~