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> {/* 對于group和mesh會(huì)是group.add的關(guān)系 而boxGeometry和MeshBasicMaterial會(huì)以mesh.boxGeometry的形式添加到mesh */} </>
自動(dòng)生成的組件要寫成駝峰 所以R3F提供的組件要寫成駝峰形式
自己定義的組件要寫成首字母大寫的
引入canvas
canvas會(huì)繼承父級的大小
#root { position: fixed; top: 0; left: 0; width: 100%; height: 100%; overflow: hidden; }
和three.js的區(qū)別
沒有創(chuàng)建scene webGLRenderer 透視相機(jī)
scene沒有被渲染
鋸齒 encoding等設(shè)置都配置好了
物體自動(dòng)放在中間
resizing是自動(dòng)配置好的 響應(yīng)式
無需引入mesh 幾何體和材質(zhì)
無需給torusKnotGeometry提供特定的值
<Canvas> <mesh> <torusKnotGeometry /> <meshNormalMaterial /> </mesh> </Canvas>
使用hook
對于幾何體 配置constructor中的參數(shù)需要在標(biāo)簽args屬性中寫
對于材質(zhì) 可以寫在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>
寫數(shù)值Number類型的值要用花括號包裹
<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)畫、旋轉(zhuǎn),直接操作mesh
- 直接操作mesh 使用useRef
- 在useFrame中使用rotation 和 delta
OrbitControls
OrbitControls不是three.js內(nèi)置的類 所以要引入它再轉(zhuǎn)為聲明式的
extend用來將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 它返回的對象包含相機(jī)和renderer,用解構(gòu)取出
const { camera, gl } = useThree(); return ( <> <orbitControls args={[camera, gl.domElement]} />//注意這里是小寫開頭 </> )
Lights
注意Basic材質(zhì)對光沒有反應(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è)置為雙面都可見 </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)過去了多少時(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)處理像素比 這可以避免性能問題
以上就是React-three-fiber使用初體驗(yàn)的詳細(xì)內(nèi)容,更多關(guān)于React-three-fiber使用的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
React?Native中原生實(shí)現(xiàn)動(dòng)態(tài)導(dǎo)入的示例詳解
在React?Native社區(qū)中,原生動(dòng)態(tài)導(dǎo)入一直是期待已久的功能,在這篇文章中,我們將比較靜態(tài)和動(dòng)態(tài)導(dǎo)入,學(xué)習(xí)如何原生地處理動(dòng)態(tài)導(dǎo)入,以及有效實(shí)施的最佳實(shí)踐,希望對大家有所幫助2024-02-02react native實(shí)現(xiàn)往服務(wù)器上傳網(wǎng)絡(luò)圖片的實(shí)例
下面小編就為大家?guī)硪黄猺eact native實(shí)現(xiàn)往服務(wù)器上傳網(wǎng)絡(luò)圖片的實(shí)例。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2017-08-08React-router?v6在Class組件和非組件代碼中的正確使用
這篇文章主要介紹了React-router?v6在Class組件和非組件代碼中的正確使用方式,具有很好的參考價(jià)值,希望對大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-03-03如何在React?Native開發(fā)中防止滑動(dòng)過程中的誤觸
在使用React?Native開發(fā)的時(shí),當(dāng)我們快速滑動(dòng)應(yīng)用的時(shí)候,可能會(huì)出現(xiàn)誤觸,導(dǎo)致我們會(huì)點(diǎn)擊到頁面中的某一些點(diǎn)擊事件,誤觸導(dǎo)致頁面元素響應(yīng)從而進(jìn)行其他操作,表現(xiàn)出非常不好的用戶體驗(yàn)。2023-05-05React路由中的redux和redux知識(shí)點(diǎn)拓展
這篇文章主要介紹了React路由中的redux和redux知識(shí)點(diǎn)拓展,文章圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,感興趣的朋友可以參考學(xué)習(xí)一下2022-08-08React Hook 父子組件相互調(diào)用函數(shù)方式
這篇文章主要介紹了React Hook 父子組件相互調(diào)用函數(shù)方式,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2022-09-09