React-three-fiber使用初體驗(yàn)
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節(jié)點(diǎn)
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是一個(gè)大的scope 從這個(gè)scope中拿到fiber這個(gè)包
<>
<group>
<mesh position={[1, 2, 3]} rotation-x={0.5}>
{/* 幾何體和材料會(huì)和mesh默認(rèn)關(guān)聯(lián) */}
<boxGeometry></boxGeometry>
<meshBasicMaterial color="red" />
</mesh>
<mesh>
<sphereGeometry></sphereGeometry>
<meshBasicMaterial color="red" />
</mesh>
</group>
{/* 對(duì)于group和mesh會(huì)是group.add的關(guān)系
而boxGeometry和MeshBasicMaterial會(huì)以mesh.boxGeometry的形式添加到mesh
*/}
</>自動(dòng)生成的組件要寫(xiě)成駝峰 所以R3F提供的組件要寫(xiě)成駝峰形式
自己定義的組件要寫(xiě)成首字母大寫(xiě)的
引入canvas
canvas會(huì)繼承父級(jí)的大小
#root {
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
overflow: hidden;
}和three.js的區(qū)別
沒(méi)有創(chuàng)建scene webGLRenderer 透視相機(jī)
scene沒(méi)有被渲染
鋸齒 encoding等設(shè)置都配置好了
物體自動(dòng)放在中間
resizing是自動(dòng)配置好的 響應(yīng)式
無(wú)需引入mesh 幾何體和材質(zhì)
無(wú)需給torusKnotGeometry提供特定的值
<Canvas>
<mesh>
<torusKnotGeometry />
<meshNormalMaterial />
</mesh>
</Canvas>使用hook
對(duì)于幾何體 配置constructor中的參數(shù)需要在標(biāo)簽args屬性中寫(xiě)
對(duì)于材質(zhì) 可以寫(xiě)在args里 也可以直接作為標(biāo)簽屬性
縮放的時(shí)候操作mesh的scale 而不是幾何體參數(shù) 為了性能
<mesh position={[2, 0, 0]} scale={1.5}>
<sphereGeometry args={[1.5, 32, 32]} />
<meshBasicMaterial color="mediumpurple" wireframe />
</mesh>寫(xiě)數(shù)值Number類型的值要用花括號(hào)包裹
<mesh position-x={2} scale={1.5}>useFrame
不管當(dāng)前的幀速度是多少,useFrame都會(huì)被調(diào)用
接收兩個(gè)參數(shù)
- state 里面有camera和clock等
- delta 1幀花費(fèi)的時(shí)間
做動(dòng)畫(huà)、旋轉(zhuǎn),直接操作mesh
- 直接操作mesh 使用useRef
- 在useFrame中使用rotation 和 delta
OrbitControls
OrbitControls不是three.js內(nèi)置的類 所以要引入它再轉(zhuǎn)為聲明式的
extend用來(lái)將three.js的class轉(zhuǎn)為聲明式的,可以在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這個(gè)hook 它返回的對(duì)象包含相機(jī)和renderer,用解構(gòu)取出
const { camera, gl } = useThree();
return (
<>
<orbitControls args={[camera, gl.domElement]} />//注意這里是小寫(xiě)開(kāi)頭
</>
)Lights
注意Basic材質(zhì)對(duì)光沒(méi)有反應(yīng)
處理陰影部分:增加環(huán)境光
自定義幾何體
抽出組件
定義Float32數(shù)組
將bufferAttribute添加到bufferGeometry(嵌套的形式) 指定這個(gè)屬性式position屬性(屬性的形式)
export default function CustomObject() {
const verticesCount = 10 * 3; //要10個(gè)三角形 每個(gè)三角形有3個(gè)頂點(diǎn)
const position = new Float32Array(verticesCount * 3); //每個(gè)頂點(diǎn)有3個(gè)值 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} />
//將材料設(shè)置為雙面都可見(jiàn)
</mesh>
);
}性能優(yōu)化 useMemo
meshStandardMaterial
計(jì)算法線 并傳遞給meshStandardMaterial
- 引入useRef 綁定在幾何體上
- 取到幾何體,并取其中的computeVertexNormals()
- 以上步奏要在useEffect上執(zhí)行 確保掛載之后有了幾何體再執(zhí)行代碼
camera設(shè)置
要讓相機(jī)做圓周運(yùn)動(dòng)
需要在x,z軸上移動(dòng)
取到已經(jīng)過(guò)去了多少時(shí)間 state.clock.getElapsedTime 作為角度
render設(shè)置
色調(diào)映射
ToonMapping是一種假的 高動(dòng)態(tài)范圍HDR到低動(dòng)態(tài)范圍
讓顏色像HDR一樣
<Canvas
gl={{
antialias: true,
toneMapping: THREE.ACESFilmicToneMapping,
outputEncoding: THREE.sRGBEncoding,//色調(diào)編碼 更好地存儲(chǔ)顏色 最好使用sRGBEncoding
}}
//使用正交相機(jī)
// 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自動(dòng)處理像素比 這可以避免性能問(wèn)題
以上就是React-three-fiber使用初體驗(yàn)的詳細(xì)內(nèi)容,更多關(guān)于React-three-fiber使用的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
封裝一個(gè)最簡(jiǎn)單ErrorBoundary組件處理react異常
這篇文章主要介紹了一個(gè)處理react異常的ErrorBoundary組件,簡(jiǎn)單實(shí)用,代碼詳細(xì),對(duì)這個(gè)組件感興趣的朋友可以參考下2021-04-04
如何將你的AngularJS1.x應(yīng)用遷移至React的方法
本篇文章主要介紹了如何將你的AngularJS1.x應(yīng)用遷移至React的方法,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-02-02
React native ListView 增加頂部下拉刷新和底下點(diǎn)擊刷新示例
這篇文章主要介紹了React native ListView 增加頂部下拉刷新和底下點(diǎn)擊刷新示例,小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧2018-04-04
react-native-fs實(shí)現(xiàn)文件下載、文本存儲(chǔ)的示例代碼
本篇文章主要介紹了react-native-fs實(shí)現(xiàn)文件下載、文本存儲(chǔ)的示例代碼,具有一定的參考價(jià)值,有興趣的可以了解下2017-09-09
React?Native?加載H5頁(yè)面的實(shí)現(xiàn)方法
這篇文章主要介紹了React?Native?加載H5頁(yè)面的實(shí)現(xiàn)方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2022-04-04
React?Refs?的使用forwardRef?源碼示例解析
這篇文章主要為大家介紹了React?之?Refs?的使用和?forwardRef?的源碼解讀,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-11-11
React中使用Workbox進(jìn)行預(yù)緩存的實(shí)現(xiàn)代碼
Workbox是Google Chrome團(tuán)隊(duì)推出的一套 PWA 的解決方案,這套解決方案當(dāng)中包含了核心庫(kù)和構(gòu)建工具,因此我們可以利用Workbox實(shí)現(xiàn)Service Worker的快速開(kāi)發(fā),本文小編給大家介紹了React中使用Workbox進(jìn)行預(yù)緩存的實(shí)現(xiàn),需要的朋友可以參考下2023-11-11
react?card?slider實(shí)現(xiàn)滑動(dòng)卡片教程示例
這篇文章主要為大家介紹了react?card?slider實(shí)現(xiàn)滑動(dòng)卡片教程示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09

