Matreial

three.js에서 기본적으로 다양한 Matreial을 제공하고 있으니 확인을 하면되겠다.

3차원 객체를 분류할 때 세가지로 나눌 수 있는데

  1. Points - 점
    • PointsMaterial
  2. Line - 선
    • LineBasicMaterial
    • LineDashedMaterial(LineBasicMaterial을 상속)
  3. Mesh - 면
    • 굉장히 많으니 직접 확인

https://threejs.org/docs/index.html?q=mater#api/en/constants/Materials

Drei 에도 다양한 Material의 종류가 있고 많이 사용되니 참고

https://github.com/pmndrs/drei#shaders


예시


const mesh1 = useRef()
const mesh2 = useRef()

useEffect(()=> {
  mesh2.current.material = mesh1.current.meterial
},[]) // mesh1의 material을 mesh2에게 공유

//..

<ambientLight intensity={0.2} />
<directionalLight position={[0,1,0]} />
<directionalLight position={[1,2,8]} intensity={0.2} />

<mesh position={[0.7, 0, 0]} ref={mesh1}>
  <boxGeometry />
  <meshBasicMaterial />
</mesh>

<mesh position={[-0.7, 0, 0]} ref={mesh2}>
  <torusGeometry args={[0.5, 0.2]} />
</mesh>

meshBasicMaterial의 경우 광원에 대해 영향을 받지 않는다.


속성


색상


<meshBasicMaterial color="affff00" />
<meshBasicMaterial color="yellow" />
<meshBasicMaterial color={0xffff00} />

wireframe


기본값 false

true로 바꾸면 mesh가 와이어 평태로 바뀐다.


Material class의 속성 적용


모든 재질에서 사용가능하다.

<meshBasicMaterial
  visible={true}
  transparent={false}
  opacity={1}
  depthTest={true}
  depthWrite={true}
  side={THREE.FrontSide} // import * as TRHEE from 'three'
  color={0xffff00}
  wireframe={false}
/>
  • opacity는 transparent가 true여야지만 작동한다.

  • depthTest, depthWrite를 이해하기 위해서는 DepthBuffer에 대해 알아야한다.

    • 간단하게 뒤에 있는 물체가 앞에 있는 물체 앞으로 올 수 없게 한다는 것, 즉 2차원에서 깊이를 나타낸다.
    • 참고 - https://2-54.tistory.com/11
  • depthTest - 렌더링되고 있는 메쉬의 픽셀을 화면에 그릴 때 depthBuffer값을 통해서 검사할 것인지
  • depthWrite - 렌더링되고 있는 메쉬의 픽셀을 depthBuffer에 기록할 것인지

  • side - mesh를 구성하는 면에 대해서 앞면만, 뒷면만, 양쪽 다 렌더링할 것인지 결정
    • THREE.FrontSide, THREE.BackSide, THREE.DoubleSide


MeshLambertMaterial


메쉬를 구성하는 정점에서 광원의 영향을 계산하는 재질

 <ambientLight intensity={0.2} />
<directionalLight position={{0,1,0}} />
<directionalLight position={{1,2,8}} intensity={0.2} />

<mesh position={[0, 7, 0, 0]} ref={mesh1}>
  <boxGeometry />
  <meshLambertMaterial
    visible={true}
    transparent={false}
    opacity={1}
    depthTest={true}
    depthWrite={true}
    side={THREE.FrontSide}
    color={0xffff00}
    wireframe={false}
    emissive={0x666600}/>
</mesh> 

emissive - 재질자체에서 방출하는 색상값


MeshPhongMaterial


메쉬가 렌더링 되는 픽셀 단위로 광원의 영향을 계산

Lambert보다 더 정교한 쉐이딩효과를 얻을 수 있다.

<mesh position={[0, 7, 0, 0]} ref={mesh1}>
  <boxGeometry />
  <meshPhongMaterial
    visible={true}
    transparent={false}
    opacity={1}
    depthTest={true}
    depthWrite={true}
    side={THREE.FrontSide}
    color={0xffff00}
    wireframe={false}
    emissive={0x00000}
    specular={0x00000}
    shininess={0}
    flatShading={false}
  />
</mesh>

specular - 광원에 의해 반사되는 색상값, 기본값은 연한회색

shininess - specular를 조정할 수 있음, 높이면 강하게 반사가 된다.

flatShading - 평평하게 렌더링할지??



물리기반 렌더링(PBR)에는 두 가지가 있으며 가장 많이 사용되는 재질이다.

meshStandardMaterial, meshPhysicalMaterial

느리지만 고품질이다.

MeshStandardMaterial


<mesh position={[0, 7, 0, 0]} ref={mesh1}>
  <boxGeometry />
  <meshStandardMaterial
    visible={true}
    transparent={false}
    opacity={1}
    depthTest={true}
    depthWrite={true}
    side={THREE.FrontSide}
    color={0xffff00}
    emissive={0x00000}
    roughness={0}
    metalness={0}
    flatShading={false}
    wireframe={false}
  />
</mesh>

roughness - 거칠기, 1이 최댓값, 사포로 갈아놓은것 같이된다.

metalness - 금속처럼 만들어준다. roughness와 함께 사용하여 다양한 재질의 느낌을 낼 수 있다.


MeshPhysicalMaterial


meshStandardMaterial을 상속받기 때문에 기존의 standard의 속성들을 그대로 사용할 수 있다.

<mesh position={[0, 7, 0, 0]} ref={mesh1}>
  <boxGeometry />
  <meshPhysicalMaterial
    visible={true}
    transparent={true}
    opacity={1}
    depthTest={true}
    depthWrite={true}
    side={THREE.DoubleSide}
    color={0xffffff}
    emissive={0x00000}
    roughness={0}
    metalness={0}
    flatShading={false}
    wireframe={false}
    // 코팅
    clearcoat={0}
    clearcoatRoughness={0}
    // 유리
    transmission={0}
    thickness={0}
    ior={1.5}
  />
</mesh>

clearcoat - 0이면 코팅이 안되어있는 재질, 1이면 최대한

clearcoatRoughness - 0이면 코딩에 거칠기가 없다. 1이면 최대

  • roughness 1, metalness 0 임에도 clearcoat를 올리면 광원효과를 받는다.

유리효과는 투명도와 관련되어 있으니 transparent={true}

transmission - 0 불투명, 1 완전 투명

thickness - 유리의 두께

ior - 유리를 통해서 보이는 물체의 굴절률, 1 ~ 2.333 사이의 값을 권장,


MeshDepthMaterial


<mesh position={[0, 7, 0, 0]} ref={mesh1}>
  <boxGeometry />
  <meshDepthMaterial />
</mesh>

기본적으로 완전히 검은 물체로 렌더링된다.

명확하게 확인하기 위해서 카메라에 near와 far 속성을 먼저 적당히 바꿔줘야함

<Canvas camera={{ near: 3.5, far: 6 }}>

카메라로부터 거리가 3.5인 픽셀지점은 그 값을 0으로 표현, 6인 지점은 1으로 표현


MeshMatcapMaterial


미리 만들어진 쉐이딩 결과 이미지를 활용, 별도의 광원을 필요로 하지 않음

MapCap 이미지를 활용하면된다.

const mapcap = useTexture("./images/mapcap.jpg")

//..

<mesh position={[0, 7, 0, 0]} ref={mesh1}>
  <boxGeometry />
  <meshMatcapMaterial matcap={mapcap} flatShading={true}/*메쉬가 각진 면으로 표현됨*/ />
</mesh>

MeshNormalMaterial


메쉬 표면에 대한 법선 벡터, 법선 벡터의 X, Y, Z를 생상 요소인 RGB값을 적용한다.


MeshToonMaterial


만화와 같은 표현을 하게 해주는 용도

별도의 텍스쳐 이미지가 필요하다.(색상톤을 나타내는 이미지)

메시의 색상을 이미지가 가지고 있는 색상톤으로 표현한다.

const texture = useTexture("./images/threeTone.jpg")

texture.minFilter = THREE.NearestFilter
texture.magFilter = THREE.NearestFilter
// 색상의 보관이 이루어지지 않게 한다.

//..

<mesh position={[0, 7, 0, 0]} ref={mesh1}>
  <boxGeometry />
  <meshToonMaterial gradientMap={texture} color="cyan"/>
</mesh>

댓글남기기