การเพิ่มโมเดลให้กับฉาก three.js
ในบทความที่แล้ว เราตั้งค่าฟิสิกส์ จากนั้นในบทความนี้ เราจะพูดถึงการโหลดโมเดล 3 มิติ สิ่งนี้มีประโยชน์จริง ๆ เนื่องจากเราเห็นว่าการสร้างวัตถุ 3 มิติใน reactor five
ข้อกำหนดเบื้องต้น
ข้อกำหนดสำหรับบทความนี้คือ คุณควรได้ทำตามบทความ การใช้ไลบรารี่ฟิสิกส์ (Adding Physics) มาก่อน
sketchfab.com
จริงๆ แล้ว วิธีที่ดีที่สุดในการนำวัตถุเข้ามาในฉากของคุณคือสร้างมันขึ้นมาด้วยแอปพลิเคชั่นอย่าง Blender เพียงดาวน์โหลดจากอินเทอร์เน็ตแล้วอัปโหลดโมเดลที่สร้างสรรค์ของคุณไปยังฉากของคุณโดยตรง ดังนั้นฉันจะใช้เว็บไซต์นี้ที่ชื่อว่า sketchfab.com และพวกเขามีโมเดลมากมายที่นี่ บางอย่างคุณต้องจ่าย บางอย่างฟรี และ อีกหนึ่งทางเลือก คือ คุณสามารถดาวน์โหลดแอปพลิเคชันอย่าง Blender ซึ่งฟรี แล้วสร้างแบบจำลองของคุณเองแล้วส่งออก
แต่เพื่อความรวดเร็ว และเพื่อประโยชน์ของเวลา เราจะดาวน์โหลดจากอินเทอร์เน็ต เราไปค้นหาคำว่า Tesla บางส่วนมีเครื่องหมายดอลลาร์อยู่ที่มุม นี่คือสิ่งที่คุณต้องจ่ายเกี่ยวกับ สิ่งที่เรากำลังมองหาคือรุ่นที่มีสัญลักษณ์ดาวน์โหลดอยู่ที่นี่ ดังนั้นสิ่งเหล่านั้นจะเป็นสิ่งที่คุณสามารถดาวน์โหลดได้ฟรี

และเราะใช้โมเดลนี้ที่อื่นจากนายคนนี้ Steven ถ้าฉันคลิก โมเดลนี้จะปรากฏขึ้น และคุณสามารถตรวจสอบโมเดลได้ จากนั้นจะมีปุ่ม ดังนั้นะดาวน์โหลดสิ่งนั้น

สร้างไฟล์ Model.jsx
สร้างไฟล์ Model.jsx ภายในโฟลเดอร์ components เขียนโค้ดดังนี้
import { useLoader } from 'react-three-fiber';
import {
GLTFLoader
} from 'three/examples/jsm/loaders/GLTFLoader';
const Model = props => {
const model = useLoader(
GLTFLoader,
props.path
)
console.log(model)
return (
<primitive
object={model.scene}
{...props}
/>
)
}
export default Model;

ไฟล์ App.js
เพิ่มโค้ดนำเข้า Model ที่ไฟล์ App.js
import Model from './components/Model';

<Suspense fallback={null}>
<Model
path='/tesla_model_3/scene.gltf'
scale={new Array(3).fill(0.01)}
position={[0,0.6,0]}
/>
</Suspense>


โค้ดไฟล์ App.js
import './App.css';
import {
Canvas, useFrame
} from 'react-three-fiber';
import { Physics } from 'use-cannon';
import { Suspense } from 'react';
import Orbit from './components/Orbit';
import Box from './components/Box';
import Background from './components/Background';
import Floor from './components/Floor';
import Bulb from './components/Bulb';
import Draggable from './components/Draggable';
import ColorPicker from './components/ColorPicker';
import Model from './components/Model';
function App() {
return (
<div style={{ height: '100vh', width: '100vw' }}>
< ColorPicker />
<Canvas
shadowMap
style={{ background: 'black' }}
camera={{ position: [7, 7, 7] }}
>
<ambientLight intensity={0.2} />
<Orbit />
<axesHelper args={[5]} />
<Physics>
<Draggable>
<Bulb position={[0, 3, 0]} />
<Suspense fallback={null}>
<Model
path='/tesla_model_3/scene.gltf'
scale={new Array(3).fill(0.01)}
position={[0,0.6,0]}
/>
</Suspense>
<Suspense fallback={null}>
<Box position={[-4, 1, 0]} />
</Suspense>
<Suspense fallback={null}>
<Box position={[4, 1, 0]} />
</Suspense>
</Draggable>
<Suspense fallback={null}>
<Background />
</Suspense>
<Floor position={[0, -0.5, 0]} />
</Physics>
</Canvas>
</div>
);
}
export default App;
เพิ่ม Model
ลบโค้ดการแสดง Box ออกไป


เพิ่ม Model
<Model
path='/tesla_model_3/scene.gltf'
scale={new Array(3).fill(0.01)}
position={[4, 0.6, 0]}
/>
<Model
path='/tesla_model_s/scene.gltf'
scale={new Array(3).fill(0.013)}
position={[-4, 0.2, 0]}
/>


แก้ไขโค้ดไฟล์ Draggable.jsx


import {
DragControls
} from 'three/examples/jsm/controls/DragControls';
import { useRef, useEffect, useState } from 'react';
import { useThree, extend } from 'react-three-fiber';
extend({ DragControls });
const Draggable = props => {
const groupRef = useRef();
const controlsRef = useRef();
const [children, setChildren] = useState([])
const { camera, gl, scene } = useThree();
useEffect(() => {
setChildren(groupRef.current.children)
}, [])
useEffect(() => {
controlsRef.current.addEventListener(
'hoveron',
e => scene.orbitControls.enabled = false
)
controlsRef.current.addEventListener(
'hoveroff',
e => scene.orbitControls.enabled = true
)
controlsRef.current.addEventListener(
'dragstart',
e => e.object.api?.mass.set(0)
)
controlsRef.current.addEventListener(
'dragend',
e => e.object.api?.mass.set(1)
)
controlsRef.current.addEventListener(
'drag',
e => {
e.object.api.position.copy(e.object.position)
e.object.api.velocity.set(0,0,0)
}
)
}, [children])
return (
<group ref={groupRef}>
<dragControls
transformGroup={props.transformGroup}
ref={controlsRef}
args={[children, camera, gl.domElement]}
/>
{props.children}
</group>
)
}
export default Draggable;
แก้โค้ดไฟล์ App.js

import "./App.css";
import { Canvas, useFrame } from "react-three-fiber";
import { Physics } from "use-cannon";
import { Suspense } from "react";
import Orbit from "./components/Orbit";
import Background from "./components/Background";
import Floor from "./components/Floor";
import Bulb from "./components/Bulb";
import Draggable from "./components/Draggable";
import ColorPicker from "./components/ColorPicker";
import Model from "./components/Model";
function App() {
return (
<div style={{ height: "100vh", width: "100vw" }}>
<ColorPicker />
<Canvas
shadowMap
style={{ background: "black" }}
camera={{ position: [7, 7, 7] }}
>
<ambientLight intensity={0.2} />
<Orbit />
<axesHelper args={[5]} />
<Bulb position={[0, 3, 0]} />
<Physics>
<Suspense fallback={null}>
<Draggable transformGroup>
<Model
path="/tesla_model_3/scene.gltf"
scale={new Array(3).fill(0.01)}
position={[4, 0.6, 0]}
/>
</Draggable>
<Draggable transformGroup>
<Model
path="/tesla_model_s/scene.gltf"
scale={new Array(3).fill(0.013)}
position={[-4, 0.2, 0]}
/>
</Draggable>
</Suspense>
<Suspense fallback={null}>
<Background />
</Suspense>
<Floor position={[0, -0.5, 0]} />
</Physics>
</Canvas>
</div>
);
}
export default App;
ผลลัพธ์การทำงาน
ดูผ่านเว็บไซต์ได้ที่