GUI(Graphical User Interface) Controller
사용자가 소프트웨어의 기능을 시각적으로 조작할 수 있도록 도와주는 인터페이스
예 : 게임에서 클릭할 수 있는 메뉴 버튼/ 설정 패널
Leva 라이브러리 활용
Leva
React 애플리케이션에서 사용 가능한 경량화된 GUI 컨트롤러 라이브러리
실시간으로 장면 속성을 조정할 수 있는 인터페이스를 제공
npm i leva
- useControls 훅을 사용하여 다양한 입력 컨트롤을 쉽게 생성하고 관리할 수 있음
- 장면 내 요소의 속성을 실시간으로 조정 가능
- 코드 몇 줄의 추가로 GUI 패널을 추가할 수 있어 편리
Leva를 활용한 3D 객체 컨트롤
useControls를 이용한 속성 조정
const options = useMemo(() => {
return {
x: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
y: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
z: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
visible: true,
color: { value: "lime" },
};
}, []);
- x, y, z 회전값을 최소 0부터 최대 2π까지 슬라이더(step: 0.01)조정 가능 설정
- visible 옵션으로 객체의 표시 여부 선택 가능
- color 속성을 변경하여 실시간 색상 조정 가능
→ 설정된 값들은 Leva 패널을 통해 실시간으로 조절 가능
App.jsx
import { Canvas } from "@react-three/fiber";
import Polyhedron from "./Polyhedron";
// Polyhedron 컴포넌트 import - 3D 오브젝트 생성
import * as THREE from "three";
import { useMemo } from "react";
// 성능 최적화를 위해 값이 변경되지 않으면 기존 값을 재사용할 수 있도록 useMemo 훅을 사용
import { Stats, OrbitControls } from "@react-three/drei";
// FPS 등 성능을 모니터링하는 Stats 컴포넌트 가져옴
import { useControls } from "leva";
// Leva 라이브러리를 이용해 GUI 컨트롤러를 추가할 수 있도록 하는 useControls 훅을 가져옴
import "./App.css";
{/* App 컴포넌트 정의 */ }
export default function App() {
// 3D 씬 생성, Polyhedron 배치, GUI 컨트롤 추가
const polyhedron = useMemo(
// useMemo를 사용하여 polyhedron 배열을 메모이제이션하여 불필요한 재생성 방지
() => [
new THREE.BoxGeometry(), // 박스 형태 3D 도형 생성
new THREE.SphereGeometry(0.785398), // 반지름 0.785398인 구형 도형 생성
new THREE.DodecahedronGeometry(0.785398), // 반지름 0.785398인 십이면체 도형 생성
],
[]
);
const options = useMemo(() => {
// GUI 컨트롤을 위한 옵션을 useMemo로 생성하여 성능 최적화
return {
// value : 초기값, min: 최소값, max: 최대값, step: 슬라이더 단위
x: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
y: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
z: { value: 0, min: 0, max: Math.PI * 2, step: 0.01 },
visible: true, // 오브젝트 가시성 여부 설정
color: { value: "lime" }, // 기본 색상 lime으로 설정
};
}, []);
const pA = useControls("Polyhedron A", options);
const pB = useControls("Polyhedron B", options);
// Leva의 GUI 컨트롤을 사용하여 "Polyhedron A", "Polyhedron B" 속성 조절 가능하도록 설정
return (
<Canvas camera={{ position: [1, 2, 3] }}>
{/* Three.js의 3D 씬을 렌더링하는 Canvas 컴포넌트
카메라를 [1, 2, 3] 좌표에 배치하여 오브젝트를 볼 수 있도록 설정 */}
<Polyhedron
// position={[-1, 1, 0]}
position={[pA.x, pA.y, pA.z]} // Leva에서 조절한 x, y, z 값을 위치 값으로 사용
rotation={[pA.x, pA.y, pA.z]} // Leva에서 조절한 x, y, z값을 회전 값으로 사용
visible={pA.visible} // Leva의 visible 속성에 따라 표시 여부 결정
color={pA.color} // Leva의 color 값을 적용
polyhedron={polyhedron} // polyhedron 배열을 전달, 도형을 변경 가능하게 함
/>
<Polyhedron
position={[1, 1, 0]} // Polyhedron B의 위치를 (1, 1, 0)으로 고정
rotation={[pB.x, pB.y, pB.z]}
visible={pB.visible}
color={pB.color}
polyhedron={polyhedron}
/>
<OrbitControls target={[0, 1, 0]} />
<axesHelper args={[5]} />
<gridHelper />
<Stats />
{/* FPS 및 성능 모니터링을 위한 Stats 컴포넌트 추가 */}
</Canvas>
);
}
- Canvas를 이용해 3D 공간 생성
- useControls를 활용해 객체별로 CUI 컨트롤 추가
- Polyhedron 컴포넌트를 활용하여 다면체 배치
Polyhedron.jsx
import { useRef, useState } from "react";
// useRef: 특정 DOM 요소나 Three.js 객체에 직접 접근할 때 사용
// useState: 상태 변화를 관리 할 때 사용
import { Mesh } from "three";
{/* Polyhedron 컴포넌트 정의 */ }
export default function Polyhedron({ polyhedron, color, ...props }) {
// polyhedron : 3D 도형 배열을 전달받음
// color : 도형의 색상을 설정하는 props
// props: 기타 추가적인 props를 받음
const ref = useRef();
// useRef를 사용해 mesh 요소에 대한 참조 생성
// Three.js 객체에 직접 접근할 때 사용
const [count, setCount] = useState(2);
// count 상태 생성, 초기값 2로 설정
// 현재 어떤 polyhedron을 사용할지 결정하는 변수
return (
<mesh
{...props} // 부모 컴포넌트에서 전달된 props 적용
ref={ref} // Three.js의 mesh 요소에 대한 참조 설정
onPointerDown={() => {
setCount((count + 1) % 3);
// 클릭할 때마다 count 값을 1 증가시키고, 3이 되면 다시 0으로 초기화
// polyhedron 배열의 인덱스를 변경하여 도형의 형태 변경
}}
geometry={polyhedron[count]}
// polyhedron 배열에서 count에 해당하는 도형을 선택적용
>
<meshBasicMaterial color={color} wireframe />
{/* meshBasicMaterial을 사용해 색상과 wireframe(와이어 형태) 적용 */}
</mesh>
);
}
- mesh 클릭 시 polyhedron 변경
- props를 받아 3D 객체 속성 설정
'React > ReactThreeFiber' 카테고리의 다른 글
Material & Texture (1) | 2025.03.05 |
---|---|
Geometry (0) | 2025.03.04 |
3D 개발을 도와주는 도구들 - OrbitControls, AxesHelper, GridHelper (0) | 2025.03.02 |
Scene (0) | 2025.02.28 |
Camera (0) | 2025.02.28 |