การเพิ่มพื้นผิว Three.js
ในความที่แล้ว เราพูดถึงเนื้อหาประเภทต่างๆ ในบทความนี้ เราจะไปที่ กำลังพูดถึงพื้นผิวก่อนที่เราจะเริ่มต้น สร้างพื้นผิวเพื่อใช้กับพื้นผิวหรือเป็นภาพสะท้อนหรือการหักเหของแสง
หมายเหตุ: หลังจากใช้งานพื้นผิวครั้งแรกแล้ว ขนาด รูปแบบ และประเภทของพื้นผิวจะไม่สามารถเปลี่ยนแปลงได้ ให้เรียก .dispose() บนเท็กซ์เจอร์ แล้วสร้างตัวอย่างใหม่
ข้อกำหนดเบื้องต้น
ข้อกำหนดสำหรับบทความนี้คือ คุณควรได้ทำตามบทความ ภาพรวมของวัสดุ (Overview of Materials) มาก่อน
Textures
เราจะต้องนำเข้า useLoader

เราจะปรับกล้องกลับลงไปที่ตำแหน่งเดิมด้วย
camera={{ position: [3, 3, 3] }}


มาเพิ่มเท็กซ์เจอร์ให้กับคิวบ์นี้กันเถอะ ลบโค้ดบางส่วน เพื่อกำจัดคุณสมบัติทั้งหมดที่เรานำไปใช้ล่าสุด


ที่โฟลเดอร์ public นำเข้าไฟล์รูปภาพ wood.jpg

และเราจะใช้ตัวโหลด useLoader เพื่อสร้างพื้นผิว ตัวโหลดประเภทแรกที่เราจะดูคือตัวโหลดพื้นผิว TextureLoader
จากนั้นเส้นทางที่คุณต้องการใช้กับ react ก็คือ เส้นทางที่สัมพันธ์กัน มาจากโฟลเดอร์ public และเลือกไฟล์เป็น wood.jpg
const texture = useLoader
(THREE.TextureLoader,
'/wood.jpg'
);

มาตั้งค่าคุณสมบัติ map property เป็นพื้นผิวที่เราเพิ่งสร้างขึ้น โดยการเพิ่ม map={texture} ที่ meshPhysicalMaterial
<meshPhysicalMaterial
map={texture}
/>

ดังนั้นสิ่งที่เราต้องการทำคือรอจนกว่าพื้นผิวจะโหลดแล้วจึงแสดงผลส่วนประกอบ ดังนั้นเพื่อเลี่ยงการใช้ async ออกไป หรือใช้ความจริง เราสามารถใช้ส่วนประกอบตอบสนองในตัวที่เรียกว่า Suspense
import { useRef, Suspense } from 'react';

โดย Suspense component จะมี props ชื่อ fallback สามารถส่ง element บางอย่างเข้าไปเพื่อจะให้แสดงระหว่างที่รอ
<Suspense fallback={null}>
<Box position={[0, 1, 0]} />
</Suspense>

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

เราจะเปลี่ยนประเภทของเรขาคณิตที่เราใช้เพื่อแสดงให้คุณเห็นว่าพื้นผิวบนทรงกลมเป็นอย่างไร
ตัวอย่างเช่น ทำให้เรื่องนี้ราบรื่นขึ้นหน่อย
<sphereBufferGeometry />


<sphereBufferGeometry args={[1,100,100]}/>

คุณจะเห็นว่าพื้นผิวกำลังจับคู่อย่างสวยงาม

Background
ที่โฟลเดอร์ public นำเข้าไฟล์รูปภาพ sky.jpg

ตอนนี้เรามาดูกันว่าเราสามารถใช้พื้นผิวกับพื้นหลัง background ของเราได้หรือไม่ เราจะสร้างองค์ประกอบใหม่ที่เรียกว่า background
const Background = props => {
const texture = useLoader(
THREE.TextureLoader,
'/sky.jpg'
)
return (
<primitive
attach='background'
object={texture}
/>
)
}

เพิ่ม Suspense
<Suspense fallback={null}>
<Background />
</Suspense>

ลบโค้ด หมอก (fog) ออก
<fog attach='fog' args={['white', 1, 10]} />



ที่โฟลเดอร์ public นำเข้าไฟล์รูปภาพ autoshop.jpg

ทดสอบเปลี่ยนภาพพื้นหลัง background


และเราจะใช้ Web Geo Kuprin หรือ Target เพื่อจัดรูปแบบอย่างถูกต้อง กระบวนการเดียวกันที่นี่
const Background = props => {
const texture = useLoader(
THREE.TextureLoader,
'/autoshop.jpg'
);
const { gl } = useThree();
const formatted = new THREE.WebGLCubeRenderTarget(
texture.image.height
).fromEquirectangularTexture(gl, texture)
return (
<primitive
attach='background'
object={formatted}
/>
)
}


ผลลัพธ์การทำงาน
โค้ด
import './App.css';
import {
Canvas,
useFrame,
useThree,
extend,
useLoader
} from 'react-three-fiber';
import { useRef, Suspense } from 'react';
import {
OrbitControls
} from 'three/examples/jsm/controls/OrbitControls';
import * as THREE from 'three'
extend({ OrbitControls });
const Orbit = () => {
const { camera, gl } = useThree();
return (
<orbitControls args={[camera, gl.domElement]} />
)
}
const Box = props => {
const ref = useRef();
const texture = useLoader(
THREE.TextureLoader,
'/wood.jpg'
);
useFrame(state => {
ref.current.rotation.y += 0.01;
ref.current.rotation.x += 0.01;
});
return (
<mesh
ref={ref}
{...props}
castShadow
// receiveShadow
>
<sphereBufferGeometry args={[1, 100, 100]} />
<meshPhysicalMaterial
map={texture}
/>
</mesh>
)
}
const Background = props => {
const texture = useLoader(
THREE.TextureLoader,
'/autoshop.jpg'
);
const { gl } = useThree();
const formatted = new THREE.WebGLCubeRenderTarget(
texture.image.height
).fromEquirectangularTexture(gl, texture)
return (
<primitive
attach='background'
object={formatted}
/>
)
}
const Floor = props => {
return (
<mesh {...props} receiveShadow>
<boxBufferGeometry args={[20, 1, 10]} />
<meshPhysicalMaterial
/>
</mesh>
)
}
const Bulb = props => {
return (
<mesh {...props}>
<pointLight castShadow />
<sphereBufferGeometry args={[0.2, 20, 20]} />
<meshPhongMaterial emissive='yellow' />
</mesh>
)
}
function App() {
return (
<div style={{ height: '100vh', width: '100vw' }}>
<Canvas
shadowMap
style={{ background: 'black' }}
camera={{ position: [3, 3, 3] }}
>
<ambientLight intensity={0.2} />
<Bulb position={[0, 3, 0]} />
<Orbit />
<axesHelper args={[5]} />
<Suspense fallback={null}>
<Box position={[0, 1, 0]} />
</Suspense>
<Suspense fallback={null}>
<Background />
</Suspense>
<Floor position={[0, -0.5, 0]} />
</Canvas>
</div>
);
}
export default App;
ดูผ่านเว็บไซต์ได้ที่