[Three.js journey 강의노트] 10

9rganizedChaos·2022년 9월 27일
0
post-thumbnail

🙌🏻 해당 글은 Three.js Journey의 강의 노트입니다.

10 Debug UI

ThreeJS를 도입해 팀프로젝트를 진행한다면, 핵심은 디버깅을 쉽게 만드는데에 있다. 타 개발자들과 디자이너, 그리고 기획자들이 가능한 많은 파라미터들을 직접 수정해볼 수 있게 만들면, 커뮤니케이션 리소스를 대폭 줄일 수 있고, 개발자가 코드를 수정하기에도 더 용이하다. HTML/CSS/JS를 통해 debug UI를 직접 만들 수도 있겠지만, 이미 ThreeJS 디버깅을 위한 나이스한 라이브러리들이 많이 존재한다.

우리는 그 중 가장 유명한 dat.GUI를 사용할 것이다.
좀 더 정확히는 lil-gui를 활용할 것인데, Dat.GUI는 사실 업데이트 되지 않은지 꽤 되어, vulnerabilities warning이 발생한다. 대신 dat.gui와 같은 방식으로 이용할 수 있는 lil-gui가 있다!

install lil-gui!

npm install --save lil-gui

lil-gui를 설치해주고 나면 아래 이미지와 같이 node_modules에서 lil-gui 폴더를 확인할 수 있다!

이렇게 설치한 lil-gui 모듈을 js 스크립트에서 임포트하자!

import './style.css'
import * as THREE from 'three'
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls.js'
import gsap from 'gsap'
import * as dat from 'lil-gui'

const gui = new dat.GUI()

위와 같이 GUI를 인스턴스화해주면 아래와 같이 브라우저 우측 상단에 GUI가 생성된 것을 확인할 수 있다.

현재는 비어있는 패널이지만, 여기에 Range, Color, Text, checkbox, select, button, folder와 같은 여러 여러 요소들을 추가해줄 수 있다.

Element 추가하기!

gui.add(mesh.position, 'y', - 3, 3, 0.01)

// 👇🏼 아래와 같은 방식으로 작성할 수도 있음
gui.add(mesh.position, 'y').min(- 3).max(3).step(0.01)

인스턴스화된 gui에 element를 추가해주려면, 위와 같이 gui.add(...) 메서드를 활용한다.
add 메서드의 첫번째 인자는 gui를 통해 조작할 대상이며, 두번째 인자는 해당 대상의 어떤 속성을 조작할지에 대한 정보를 넘겨주면 된다!

또한, 셋째, 넷째 인자와 다섯번째 인자를 조작하여, 각각 최솟값과 최댓값, 그리고 값의 단위를 지정해줄 수도 있다.

gui
    .add(mesh.position, 'y')
    .min(- 3)
    .max(3)
    .step(0.01)
    .name('elevation')

name() 메소드를 이용하면 gui 패널에 등장하는 label의 이름을 변경할 수 있다.

이외에도 다양한 속성들을 gui로 컨트롤 할 수 있다.

const gui = new dat.GUI()
gui.add(mesh.position, 'y', - 3, 3, 0.01).name('elevation')
gui.add(mesh, 'visible')
gui.add(material, 'wireframe')

Colors

색상을 조정하는 것은 다른 속성을 컨트롤하는 것과는 조금 다르다. 우선 add() 메소드 대신, addColor() 메소드를 활용한다. 또한, 우리는 직접 #ff0000 같은 값을 넘기지 않고, parameters라는 객체를 만들어주고 이를 활용해 간접적으로 material의 색상을 변경해주어야 한다. (lil-gui에서는 아래 코드에 주석처리해놓은 부분과 같이 직접 material를 컨트롤할 수 있도록 할 수 있지만, 중간에 매개 객체를 두는 방식을 후에 활용하게 되므로 우선 이 방식을 학습한다.)

const parameters = {
    color: 0xff0000
}

const geometry = new THREE.BoxGeometry(1, 1, 1)
const material = new THREE.MeshBasicMaterial({ color: 0xff0000 })
const mesh = new THREE.Mesh(geometry, material)
scene.add(mesh)

const gui = new dat.GUI()
// gui.addColor(material, 'color') 👈🏼 (lil-gui에서는) 이렇게 적어주어도 동작은 함
gui.addColor(parameters, 'color').onChange(() =>
{
    material.color.set(parameters.color)
})

위 코드의 로직은 아래와 같다.
1) GUI 패널에서 Color picker를 통해 parameters의 컬러를 변경한다.
2) onChange가 동작해, material의 컬러를 변경된 parameters의 color로 변경해준다.

Functions

GUI를 통해서 함수를 트리거해줄 수도 있다. 이때, 위 예제에서 만들어두었던 parameters 객체를 이용하자! 먼저 예제로 큐브를 한 바퀴 돌리는 spin 함수를 만들어볼 것이다.

const parameters = {
    color: 0xff0000,
    spin: () =>
    {
        gsap.to(mesh.rotation, { duration: 1, y: mesh.rotation.y + Math.PI * 2 })
    }
}

gui.add(parameters, 'spin')

Tips

공식문서의 첫 부분을 확인하면, gui를 인스턴스화하면서 다양한 옵션들을 지정해줄 수 있다는 것을 알 수 있다.

  • autoPlace: (boolean / default: true) GUI를 페이지의 오른쪽 상단에 고정할 것인가의 여부
  • container: (HTMLElement / optional) GUI를 특정 HTML엘리먼트에 추가하고 싶을 때 활성화. 이 속성을 사용하면 autoPlace 속성을 뒤집어쓰게 된다.
  • width: (number / default: 245) GUI 패널의 너비 지정
  • title: (string / default: Controls) 패널 상단에 표시되는 이름
  • injectStyles: (boolean / default: true) 기본으로 제공되는 styleSheet을 활용한다면 true로 커스텀 styleSheet을 활용한다면 false
  • touchStyles: (boolean / default: true) 터치 가능한 디바이스에서 컨트롤러를 더욱 크게 만드는 옵션
  • parent: (GUI / optional) 해당 GUI를 또 다른 GUI의 자식으로 추가하기 위한 옵션, 보통 addFolder()와 함께 활용하게 된다.
profile
부정확한 정보나 잘못된 정보는 댓글로 알려주시면 빠르게 수정토록 하겠습니다, 감사합니다!

1개의 댓글

comment-user-thumbnail
2023년 5월 15일

공유해주신 강의노트 잘보고 있습니다.
강의노트 11, 13 부분 포스트가 빠져있네요. 혹시 것도 공유해주실수 있으실까요?

답글 달기