เจาะลึก React และ Three.js โดยใช้ react-three-fiber
เผยแพร่แล้ว: 2022-03-10react-three-fiber
เป็นโปรแกรมเรนเดอร์ Three.js อันทรงพลังที่ช่วยเรนเดอร์โมเดล 3 มิติและแอนิเมชั่นสำหรับ React และแอปพลิเคชันดั้งเดิม ในบทช่วยสอนนี้ คุณจะได้เรียนรู้วิธีกำหนดค่าและสร้างโมเดล 3 มิติในแอปพลิเคชัน React วันนี้ เราจะมาเรียนรู้วิธีกำหนดค่าและใช้ react-three-fiber
สำหรับการสร้างและแสดงโมเดล 3 มิติและแอนิเมชั่นในแอปพลิเคชัน React และ React Native
บทช่วยสอนนี้มีไว้สำหรับนักพัฒนาที่ต้องการเรียนรู้เพิ่มเติมเกี่ยวกับแอนิเมชั่นโมเดล 3 มิติในเว็บโดยใช้ React และสำหรับใครก็ตามที่มีข้อจำกัดกับ Three.js เช่น ไม่สามารถสร้างแคนวาสได้ ผูกเหตุการณ์ของผู้ใช้ เช่น เหตุการณ์การ click
และเริ่มการวนรอบการเรนเดอร์ react-three-fiber
- react-three-fiber
มาพร้อมกับวิธีการเหล่านี้ เรากำลังจะสร้างโมเดล 3 มิติเพื่อให้เข้าใจถึงวิธีการสร้างโมเดล Three.js 3D โดยใช้ react-three-fiber
เริ่มต้นใช้งาน react-three-fiber
Three.js เป็นไลบรารีที่ช่วยให้สร้างกราฟิก 3 มิติในเบราว์เซอร์ได้ง่ายขึ้น โดยใช้ผ้าใบ + WebGL เพื่อแสดงโมเดล 3 มิติและแอนิเมชั่น คุณสามารถเรียนรู้เพิ่มเติมได้ที่นี่
react-three-fiber เป็น React renderer สำหรับ Three.js บนเว็บและ react-native เป็นการเพิ่มความเร็วที่คุณสร้างแบบจำลอง 3 มิติและแอนิเมชั่นด้วย Three.js ตัวอย่างบางส่วนของไซต์ที่มีโมเดล 3 มิติและแอนิเมชั่น สามารถพบได้ที่นี่ react-three-fiber
ช่วยลดเวลาที่ใช้กับแอนิเมชั่นเนื่องจากส่วนประกอบที่ใช้ซ้ำได้ เหตุการณ์ที่ผูกมัด และการแสดงวนซ้ำ อันดับแรก เรามาดูกันว่า Three.js คืออะไร
react-three-fiber
ช่วยให้เราสร้างส่วนประกอบของโค้ด threeJS
โดยใช้สถานะ React, hooks และ props นอกจากนี้ยังมาพร้อมกับองค์ประกอบต่อไปนี้:
องค์ประกอบ | คำอธิบาย |
---|---|
mesh | คุณสมบัติที่ช่วยกำหนดรูปร่างของโมเดลของเรา |
hooks | react-three-fiber กำหนด hooks ที่ช่วยให้เราเขียนฟังก์ชันที่ช่วยกำหนดเหตุการณ์ของผู้ใช้ เช่น onClick และ onPointOver |
วนตามคอมโพเนนต์และเรนเดอร์ | react-three-fiber เป็นส่วนประกอบและแสดงผลตามการเปลี่ยนแปลงในสถานะหรือร้านค้า |
วิธีใช้ react-three-fiber
ในการใช้ react-three-fiber
คุณเริ่มต้นด้วยการใช้คำสั่งด้านล่าง:
NPM
npm i three react-three-fiber
เส้นด้าย
yarn add three react-three-fiber
หมายเหตุ : เพื่อให้ react-three-fiber
ทำงานได้ คุณจะต้องติดตั้ง three
(Three.js) ตามที่เราดำเนินการข้างต้น
การสร้างแบบจำลอง React 3D Ludo Dice และโครงการแอนิเมชั่น
ที่นี่เราจะสร้างแบบจำลองลูกเต๋าลูโด 3 มิติโดยใช้ react-three-fiber
อย่างที่เรามีในวิดีโอด้านล่าง
เราจะใช้ create-react-app
เพื่อเริ่มต้นโปรเจ็กต์ ให้รันคำสั่งด้านล่างบนเทอร์มินัลของเรา
create-react-app react-three-fiber-ludo-model
คำสั่งด้านบนเริ่มต้นโปรเจ็กต์ React ภายในเครื่องของเรา ต่อไป cd
ลงในไดเร็กทอรีและติดตั้งแพ็คเกจ react-three-fiber
และ three
cd react-three-fiber-ludo-model npm i three react-three-fiber
เมื่อติดตั้งแพ็คเกจแล้ว มาเริ่มเซิร์ฟเวอร์การพัฒนาของเราโดยใช้คำสั่ง
npm start
คำสั่งข้างต้นควรเริ่มต้นเซิร์ฟเวอร์การพัฒนาโครงการของเราในเบราว์เซอร์ของเรา ต่อไป ให้เปิดโครงการของเราในโปรแกรมแก้ไขข้อความที่เราเลือก ภายในโฟลเดอร์โครงการ src
ของเรา ให้ลบไฟล์ต่อไปนี้: App.css
, App.test.js
, serviceWorker.js
และ setupTests.js
ต่อไป มาลบโค้ดทั้งหมดที่อ้างอิงถึงไฟล์ที่ถูกลบใน App.js
ของเรา
สำหรับโปรเจ็กต์นี้ เราจะต้องมีองค์ประกอบ Box
สำหรับลูกเต๋าลูโดและส่วนประกอบ App
ของเราที่ได้รับจาก React
การสร้างส่วนประกอบ Box
องค์ประกอบของ Box
จะประกอบด้วยรูปร่างสำหรับลูกเต๋าลูโด รูปภาพของลูกเต๋าลูโด และสถานะที่จะหมุนตลอดเวลา อันดับแรก มานำเข้าแพ็คเกจทั้งหมดที่เราต้องการสำหรับองค์ประกอบ Box
ด้านล่าง
import React, { useRef, useState, useMemo } from "react"; import { Canvas, useFrame } from "react-three-fiber"; import * as THREE from "three"; import five from "./assets/five.png";
ในโค้ดด้านบนนี้ เรากำลังนำเข้า useRef
, useState
และ useMemo
เราจะใช้ useRef
hook เพื่อเข้าถึงเมชของลูกเต๋าและ useState
hook เพื่อตรวจสอบสถานะแอ็คทีฟของ ludo dice useMemo
hook จะใช้คืนหมายเลขบนลูกเต๋า ต่อไป เรากำลังนำเข้า Canvas
และ useFrame
จาก react-three-fiber
canvas
ใช้เพื่อวาดกราฟิกบนเบราว์เซอร์ ในขณะที่ useFrame
อนุญาตให้ส่วนประกอบเชื่อมต่อเข้ากับ render-loop ซึ่งทำให้องค์ประกอบหนึ่งสามารถแสดงผลได้ เนื้อหาของผู้อื่น ต่อไป เรานำเข้าแพ็คเกจ three
ชุด จากนั้นเรานำเข้าภาพนิ่งของลูกเต๋าลูโด
ต่อไปสำหรับเราคือการเขียนตรรกะสำหรับองค์ประกอบ Box
ของเรา อันดับแรก เราจะเริ่มด้วยการสร้างองค์ประกอบการทำงานและเพิ่มสถานะให้กับองค์ประกอบของเรา มาทำกันด้านล่าง
const Box = (props) => { const mesh = useRef(); const [active, setActive] = useState(false); useFrame(() => { mesh.current.rotation.x = mesh.current.rotation.y += 0.01; }); const texture = useMemo(() => new THREE.TextureLoader().load(five), []); return ( <Box /> ); }
ในโค้ดด้านบน เรากำลังสร้างองค์ประกอบ Box
ด้วย props ต่อไป เราสร้าง ref ที่เรียกว่า mesh
โดยใช้ useRef
hook เราทำสิ่งนี้เพื่อให้เราสามารถส่งคืนเมชเดิมได้ทุกครั้ง
ตาข่ายเป็นองค์ประกอบภาพในฉาก เป็นวัตถุ 3 มิติที่ประกอบเป็นรูปหลายเหลี่ยมสามเหลี่ยม มักสร้างโดยใช้ เรขาคณิต ซึ่งใช้ในการกำหนดรูปร่างของแบบจำลองและ วัสดุ ที่กำหนดลักษณะที่ปรากฏของแบบจำลอง คุณสามารถ เรียนรู้เกี่ยวกับ Mesh ที่นี่ คุณยังสามารถเรียนรู้เพิ่มเติมเกี่ยวกับ useRef
hook ที่นี่

หลังจากเริ่มต้น mesh
เราจำเป็นต้องเริ่มต้นสถานะสำหรับแอปพลิเคชันของเราโดยใช้ useState
hook ที่นี่เราตั้งค่าสถานะโฮเวอร์และแอ็คทีฟของแอปพลิเคชันเป็นเท็จ
ต่อไป เราใช้ useFrame
hook จาก react-three-fiber
เพื่อหมุนตาข่าย (ludo dice) โดยใช้รหัสด้านล่าง
mesh.current.rotation.x = mesh.current.rotation.y += 0.01;
ที่นี่ เรากำลังหมุนตำแหน่งปัจจุบันของตาข่ายทุกๆ 0.01 วินาที ซึ่งทำขึ้นเพื่อให้การหมุนมีภาพเคลื่อนไหวที่ดี
const texture = useMemo(() => new THREE.TextureLoader().load(five), []);
ในโค้ดด้านบนนี้ เรากำลังสร้างค่าคงที่ที่เรียกว่า texture
เจอร์ และส่งผ่าน useMemo
hook แบบ react เป็นฟังก์ชันเพื่อโหลดการทอยลูกเต๋าใหม่ ที่นี่ useMemo
เพื่อจดจำภาพลูกเต๋าและหมายเลขของมัน คุณสามารถเรียนรู้เกี่ยวกับ useMemo
hook ได้ที่นี่
ต่อไป เราต้องการแสดงองค์ประกอบ Box
บนเบราว์เซอร์และเพิ่มกิจกรรมของเรา เราทำที่ด้านล่าง
const Box = (props) => { return ( <mesh {...props} ref={mesh} scale={active ? [2, 2, 2] : [1.5, 1.5, 1.5]} onClick={(e) => setActive(!active)} > <boxBufferGeometry args={[1, 1, 1]} /> <meshBasicMaterial attach="material" transparent side={THREE.DoubleSide}> <primitive attach="map" object={texture} /> </meshBasicMaterial> </mesh> ); }
ในโค้ดด้านบน เรากำลังส่งคืนส่วนประกอบ Box
ของเราและห่อไว้ใน mesh
เราส่งผ่านคุณสมบัติทั้งหมดของส่วนประกอบ Box
โดยใช้ตัวดำเนินการ spread จากนั้นเราอ้างอิง mesh โดยใช้ useRef
hook ต่อไป เราใช้คุณสมบัติ scale
จาก Three.js เพื่อกำหนดขนาดของกล่องลูกเต๋าเมื่อเปิดใช้งานเป็น 2 และ 1.5 เมื่อไม่ได้ใช้งาน สุดท้ายแต่ไม่ท้ายสุด เราได้เพิ่มเหตุการณ์ onClick
เพื่อตั้งค่า state
เป็น active
หากไม่ได้ตั้งค่าเป็นค่าเริ่มต้น
<boxBufferGeometry args={[1, 1, 1]} />
เพื่อแสดงกล่องลูกเต๋า เราแสดงผลองค์ประกอบ boxBufferGeometry
จาก Three.js, boxBufferGeometry
ช่วยให้เราวาดเส้นและจุดเช่นกล่อง เราใช้ args
เพื่อส่งผ่านตัวสร้างเช่นขนาดของกล่องเรขาคณิต
<meshBasicMaterial attach="material" transparent side={THREE.DoubleSide}>
meshBasicMaterial
จาก Three.js ใช้ในการวาดรูปทรงเรขาคณิตในรูปแบบง่ายๆ ที่นี่เราส่งแอตทริบิวต์ attach
และส่งอุปกรณ์ประกอบฉาก THREE.DoubleSide
ไปยังแอตทริบิวต์ side
THREE.DoubleSide
กำหนดด้านหรือช่องว่างที่ควรแสดงโดย react-three-fiber
<primitive attach="map" object={texture} />
องค์ประกอบ primitive
จาก Three.js ใช้ในการวาดกราฟ 3 มิติ เราแนบคุณสมบัติแผนที่เพื่อรักษารูปร่างดั้งเดิมของลูกเต๋าลูโด ต่อไป เราจะสร้างองค์ประกอบ Box
ของเราในไฟล์ App.js
และทำกล่องลูกเต๋าลูโด 3 มิติให้สมบูรณ์ ส่วนประกอบของคุณควรมีลักษณะคล้ายกับภาพด้านล่าง

แสดงผล 3D Ludo Dice Box
ในส่วนนี้ เราจะสร้างองค์ประกอบ Box
ของเราใน App.js
และทำกล่อง 3d ludo ให้สมบูรณ์ อันดับแรก ให้สร้างองค์ประกอบ App
และห่อด้วยแท็ก Canvas
เพื่อสร้างโมเดล 3 มิติของเรา ลองทำกันด้านล่าง
const App = () => { return ( <Canvas> </Canvas> ); } export default App;
ต่อไป มาเพิ่มไฟให้กับกล่องกัน react-three-fiber
ให้ส่วนประกอบ 3 อย่างแก่โมเดลของเราซึ่งมีดังนี้
-
ambientLight
ใช้สำหรับให้แสงวัตถุทั้งหมดในฉากหรือแบบจำลองเท่าๆ กัน โดยรับอุปกรณ์ประกอบฉาก เช่น ความเข้มของแสง ซึ่งจะทำให้ร่างกายของลูกเต๋าลูโดสว่างขึ้น -
spotLight
แสงนี้ถูกปล่อยออกมาจากทิศทางเดียว และจะเพิ่มขึ้นเมื่อขนาดของวัตถุเพิ่มขึ้น ซึ่งจะทำให้จุดของลูกเต๋าลูโดสว่างขึ้น -
pointLight
การทำงานนี้คล้ายกับแสงของหลอดไฟ แสงถูกปล่อยออกมาจากจุดเดียวไปยังทุกทิศทาง ซึ่งจำเป็นสำหรับสถานะแอ็คทีฟของแอปพลิเคชันของเรา
มาปรับใช้ข้างต้นกับแอปพลิเคชันของเราด้านล่าง
const App = () => { return ( <Canvas> <ambientLight intensity={0.5} /> <spotLight position={[10, 10, 10]} angle={0.15} penumbra={1} /> <pointLight position={[-10, -10, -10]} /> </Canvas> ); } export default App;
ในโค้ดด้านบน เรานำเข้าส่วนประกอบ ambientLight
จาก react-three-fiber
และเพิ่มความเข้ม 0.5 ลงไป ต่อไปเราได้เพิ่มตำแหน่งและมุมให้กับส่วนประกอบ spotLight
และ pointLight
ของเรา ขั้นตอนสุดท้ายสำหรับแอปพลิเคชันของเราคือสร้างองค์ประกอบกล่องและเพิ่มตำแหน่งให้กับกล่องลูกเต๋าลูโด เราจะทำในโค้ดด้านล่าง
<Box position={[-1.2, 0, 0]} /> <Box position={[2.5, 0, 0]} />
เมื่อเสร็จแล้ว ludo 3D dice ของคุณควรมีลักษณะคล้ายกับภาพด้านล่าง:

การสาธิตการทำงานมีอยู่ใน CodeSandbox
บทสรุป
react-three-fiber
ทำให้การเรนเดอร์โมเดล 3 มิติและแอนิเมชั่นสร้างได้ง่ายขึ้นสำหรับแอปพลิเคชัน React และ React Native ด้วยการสร้างกล่องลูกเต๋า 3D ludo เราได้เรียนรู้เกี่ยวกับพื้นฐานของ Three.js ควบคู่ไปกับส่วนประกอบและประโยชน์ของ react-three-fiber
รวมถึงวิธีใช้งาน
คุณสามารถดำเนินการเพิ่มเติมได้โดยการสร้างโมเดล 3 มิติและแอนิเมชั่นในแอปพลิเคชัน React และ Native โดยใช้ react-three-fiber
ด้วยตัวคุณเอง ฉันชอบที่จะเห็นสิ่งใหม่ ๆ ที่คุณคิด!
คุณสามารถอ่านเพิ่มเติมเกี่ยวกับ Three.js และ react-three-fiber
ได้ในข้อมูลอ้างอิงด้านล่าง
แหล่งข้อมูลที่เกี่ยวข้อง
- เอกสารประกอบของ Three.js
- ปัจจัยพื้นฐาน Three.js
- React-Three-fiber GitHub repo โดย Poimandres
- เอกสารประกอบปฏิกิริยาสามไฟเบอร์
- React Hooks (useState, useMemo, ฯลฯ ) เอกสารอย่างเป็นทางการ