React-three-fiber使用初体验
作者:boombb
React-three-fiber
npm init -y npm install react@18 react-dom@18.2 react-scripts@5.0
在package.json
"scripts": { "dev": "react-scripts start", "build": "react-scripts build", }
新建public和src文件夾 分別新建index文件
src/index.js import { createRoot } from "react-dom/client"; import "./style.css"; // 拿到root节点 const root = createRoot(document.querySelector("#root"));
安装R3F包和three.js依赖
npm install three@0.145 @react-three/fiber@8.8
@react-three/fiber@8.8 中@react-three是一个大的scope 从这个scope中拿到fiber这个包
<> <group> <mesh position={[1, 2, 3]} rotation-x={0.5}> {/* 几何体和材料会和mesh默认关联 */} <boxGeometry></boxGeometry> <meshBasicMaterial color="red" /> </mesh> <mesh> <sphereGeometry></sphereGeometry> <meshBasicMaterial color="red" /> </mesh> </group> {/* 对于group和mesh会是group.add的关系 而boxGeometry和MeshBasicMaterial会以mesh.boxGeometry的形式添加到mesh */} </>
自动生成的组件要写成驼峰 所以R3F提供的组件要写成驼峰形式
自己定义的组件要写成首字母大写的
引入canvas
canvas会继承父级的大小
#root { position: fixed; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; }
和three.js的区别
没有创建scene webGLRenderer 透视相机
scene没有被渲染
锯齿 encoding等设置都配置好了
物体自动放在中间
resizing是自动配置好的 响应式
无需引入mesh 几何体和材质
无需给torusKnotGeometry提供特定的值
<Canvas> <mesh> <torusKnotGeometry /> <meshNormalMaterial /> </mesh> </Canvas>
使用hook
对于几何体 配置constructor中的参数需要在标签args属性中写
对于材质 可以写在args里 也可以直接作为标签属性
缩放的时候操作mesh的scale 而不是几何体参数 为了性能
<mesh position={[2, 0, 0]} scale={1.5}> <sphereGeometry args={[1.5, 32, 32]} /> <meshBasicMaterial color="mediumpurple" wireframe /> </mesh>
写数值Number类型的值要用花括号包裹
<mesh position-x={2} scale={1.5}>
useFrame
不管当前的帧速度是多少,useFrame都会被调用
接收两个参数
- state 里面有camera和clock等
- delta 1帧花费的时间
做动画、旋转,直接操作mesh
- 直接操作mesh 使用useRef
- 在useFrame中使用rotation 和 delta
OrbitControls
OrbitControls不是three.js内置的类 所以要引入它再转为声明式的
extend用来将three.js的class转为声明式的,可以在jsx中使用
import { useThree, extend, useFrame } from "@react-three/fiber"; import { OrbitControls } from "three/examples/jsm/controls/OrbitControls.js"; extend({ OrbitControls }); //orbitControls在jsx中使用的名称
OrbitControls需要传入camera和renderer.domElement:使用useThree这个hook 它返回的对象包含相机和renderer,用解构取出
const { camera, gl } = useThree(); return ( <> <orbitControls args={[camera, gl.domElement]} />//注意这里是小写开头 </> )
Lights
注意Basic材质对光没有反应
处理阴影部分:增加环境光
自定义几何体
抽出组件
定义Float32数组
将bufferAttribute添加到bufferGeometry(嵌套的形式) 指定这个属性式position属性(属性的形式)
export default function CustomObject() { const verticesCount = 10 * 3; //要10个三角形 每个三角形有3个顶点 const position = new Float32Array(verticesCount * 3); //每个顶点有3个值 x y z for (let i = 0; i < verticesCount * 3; i++) { position[i] = (Math.random() - 0.5) * 3; // * 3为了让三角形不那么小 } return ( <mesh> <bufferGeometry> <bufferAttribute attach="attributes-position" count={verticesCount} itemSize={3} array={position} /> </bufferGeometry> <meshBasicMaterial side={THREE.DoubleSide} /> //将材料设置为双面都可见 </mesh> ); }
性能优化 useMemo
meshStandardMaterial
计算法线 并传递给meshStandardMaterial
- 引入useRef 绑定在几何体上
- 取到几何体,并取其中的computeVertexNormals()
- 以上步奏要在useEffect上执行 确保挂载之后有了几何体再执行代码
camera设置
要让相机做圆周运动
需要在x,z轴上移动
取到已经过去了多少时间 state.clock.getElapsedTime 作为角度
render设置
色调映射
ToonMapping是一种假的 高动态范围HDR到低动态范围
让颜色像HDR一样
<Canvas gl={{ antialias: true, toneMapping: THREE.ACESFilmicToneMapping, outputEncoding: THREE.sRGBEncoding,//色调编码 更好地存储颜色 最好使用sRGBEncoding }} //使用正交相机 // orthographic camera={{ fov: 45, near: 0.1, far: 200, position: [2, 3, 3], }} >
在css中
#root { position: fixed; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; /* 改背景颜色 */ background: lightblue; }
R3F自动处理像素比 这可以避免性能问题
以上就是React-three-fiber使用初体验的详细内容,更多关于React-three-fiber使用的资料请关注脚本之家其它相关文章!