ภาพรวมของวัสดุ (Overview of Materials)

ภาพรวมของวัสดุ Three.js

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

ข้อกำหนดเบื้องต้น


ข้อกำหนดสำหรับบทความนี้คือ คุณควรได้ทำตามบทความ แสงและเงา (Lights and Shadows) มาก่อน


ในบทความที่แล้ว เราได้ตั้งค่า Light and Shadows ในบทความนี้ เราจะทำ มองลึกลงไปในวัสดุ (Material)

เริ่มต้นด้วยการย้ายกล่องนี้ไปไว้ใต้แสงของเรา และกำจัดการหมุนของแกน x

<Box position={[0, 1, 0]} />

และจะขยับกล้องขึ้นไปอีกเล็กน้อยเพื่อให้เราเห็นแสง สะท้อนที่ด้านบน ของลูกบาศก์ของเรา

camera={{ position: [1, 5, 1] }}

Overview of Materials


วัสดุเป็นคลาสพื้นฐานนามธรรมสำหรับวัสดุ คุณสมบัติบางอย่างที่เราคุ้นเคยอยู่แล้ว เช่น สีและด้านข้าง. นอกจากนี้ยังมีด้านเงาที่กำหนดว่าด้านใดของใบหน้าจะทำให้เกิดเงา property อีกอย่างเรียกว่า Phog คุณสมบัตินี้กำหนดว่าวัสดุได้รับผลกระทบจากหมอก (fog) หรือไม่

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

<fog args={['white', 1, 2]} />


อะไรก็ตามที่อยู่ใน canvas ของเรา จะถูกส่งต่อไปยังที่ scene และ child แต่ในกรณีของหมอกเราต้องการ เพื่อติดเข้ากับคุณสมบัติหมอกของที่เกิดเหตุเลยขอเพิ่มแนบหมอก attach=’fog’

<fog attach='fog' args={['white', 1, 2]} />

เอาล่ะ รีเฟรชหน้าแล้วเราก็เจอหมอกหนาทึบที่นี่

มาทำให้หนาแน่นน้อยลงหน่อย เราจะเปลี่ยนแอตทริบิวต์ far เป็น 10

<fog attach='fog' args={['white', 1, 10]} />


นั่นดีกว่า. เมื่อเราซูมออก ก็มีหมอกอยู่บ้าง


ตอนนี้กลับไปที่เนื้อหา Materials เรากำลังบอกว่าคุณสมบัติของหมอกบนวัสดุกำหนดว่าได้รับผลกระทบจากหมอกหรือไม่

ค่าเริ่มต้นเป็นจริง แต่ถ้าฉันไปที่กล่องของฉันแล้วตั้งค่า Fog เป็น false บนวัสดุ ให้รีเฟรชหน้า ตอนนี้กล่องนี้ไม่ได้รับผลกระทบจากหมอกอีกต่อไป โดยวัตถุอื่นๆ ทั้งหมดมีหมอก แต่ไม่ใช่กล่องนี้

<meshPhysicalMaterial color='blue' fog={false}/>

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

<meshPhysicalMaterial
    color='blue'
    opacity={0.5}
/>


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

แสดงการโปร่งใสหรือไม่ มาเพิ่มคุณสมบัติโปร่งใส transparent


ตอนนี้ มีความทึบน้อยกว่า และ ทึบแสงมากขึ้น

คุณสมบัติสุดท้ายที่เราต้องการพูดถึงในคลาสฐานวัสดุสามารถมองเห็นได้และกำหนดว่า ให้เราเห็นวัตถุหรือไม่ ค่าเริ่มต้น visible เป็น true แต่ถ้าตั้งค่าที่มองเห็นได้เป็น false จะไม่เห็นวัตถุ

visible={false}

wireframe

เราจะเข้าใจคุณสมบัติบางอย่างในคลาสวัสดุพื้นฐานได้อย่างไร

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

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

คุณสมบัติต่อไปที่ฉันต้องการพูดคุยเกี่ยวกับการทำความเข้าใจวัสดุคือคุณสมบัติ Wireframe

ปกติแล้วก่อนที่เราจะทำอะไรสักอย่าง เราก็ควรที่จะร่างแผนงานออกมาคร่าวๆก่อนเสมอ ถ้าจะให้พูดตัว Wireframe ก็คือแผนงานที่ถูกร่างขึ้นมานั่นเอง โดย Wireframe นั้นจะไม่มีรายละเอียดด้านความสวยงาม เช่นสี หรือรูปภาพที่ใช้บนหน้าเว็บ แต่จะแสดงเฉพาะ layout, ส่วนประกอบบนหน้าเว็บ และอาจมีรายละเอียดเพิ่มเติมของส่วนต่างๆบนหน้าเว็บ เช่นการเชื่อมโยงของลิ้งต่างๆ หรือ animation

wireframe

นี่ก็แค่แสดงจุดยอดและเส้นตรงที่สร้างโดยเรขาคณิต โปรดสังเกตว่าเงายังแสดง

metalness

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

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

metalness={1}

Roughness

Roughness คือ ความหยาบของผิวชิ้นงาน หรือบางคนก็อาจจะเรียกกันว่า ความเรียบผิว ก็ได้เช่นกัน ที่เกิดจากการแปรรูปงานรูปแบบหนึ่ง

roughness={0}

นำ //metalness={1} ออก

Clearcoat

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

transmission

ให้เห็นเอฟเฟกต์การส่งสัญญาณผ่านเนื้อหาทางกายภาพ

transmission={1}

reflectivity


reflectivity การสะท้อนแสง แผนที่สิ่งแวดล้อมมีผลกระทบต่อพื้นผิวมากน้อยเพียงใด ดู .combin ด้วย ค่าเริ่มต้นคือ 1 และช่วงที่ถูกต้องคือระหว่าง 0 (ไม่มีการสะท้อน) และ 1 (การสะท้อนเต็ม)

<meshPhysicalMaterial
    color='white'
    transparent
    //metalness={1}
    roughness={0} 
    clearcoat={1} 
    transmission={0.5} 
    reflectivity={1}       
/>

side

side: กำหนดด้านใดของใบหน้าที่จะแสดงผล – ด้านหน้า ด้านหลัง หรือทั้งสองอย่าง ค่าเริ่มต้นคือ THREE.FrontSide ตัวเลือกอื่นๆ ได้แก่ THREE.BackSide และ THREE.DoubleSide

side={THREE.DoubleSide} 

ผลลัพธ์การทำงาน


โค้ด

import './App.css';
import { Canvas, useFrame, useThree, extend } from 'react-three-fiber';
import { useRef } 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();
  useFrame(state => {
    ref.current.rotation.y += 0.01;
    ref.current.rotation.x += 0.01;
  });

  return (
    <mesh ref={ref}
      {...props}
      castShadow
      // receiveShadow
    >
      <boxBufferGeometry />
      <meshPhysicalMaterial
        color='white'
        transparent
        //metalness={1}
        roughness={0} 
        clearcoat={1} 
        transmission={0.5} 
        reflectivity={1} 
        side={THREE.DoubleSide}      
      />
    </mesh>
  )
}

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: [1, 5, 1] }}
      >
        <fog attach='fog' args={['white', 1, 10]} />
        <ambientLight intensity={0.2} />
        <Bulb position={[0, 3, 0]} />
        <Orbit />
        <axesHelper args={[5]} />
        <Box position={[0, 1, 0]} />
        <Floor position={[0, -0.5, 0]} />
      </Canvas>
    </div>
  );
}

export default App;

ดูผ่านเว็บไซต์ได้ที่

Leave a Reply

Your email address will not be published.