TIL 118 | Three.js 기초 - 3D Text

meow·2025년 3월 16일
0

Interactive

목록 보기
8/11
post-thumbnail

TextGeometry

TextGeometry는 Three.js에서 3D 텍스트를 생성하는 데 사용되는 기하학적 형상(Geometry)입니다. 일반적인 2D 텍스트가 아닌 3D 입체 문자를 생성할 수 있으며, 다른 Mesh 객체처럼 Material을 적용하여 스타일링할 수 있습니다.

아래 주소에 접속하여 타입 파일을 올리면 JSON으로 변환할 수 있다. 라이센스가 있는 폰트는 같은 디렉토리에 라이센스 파일을 두는 것을 잊지 말자.
http://gero3.github.io/facetype.js/


1. TextGeometry 사용법

TextGeometry를 사용하려면 Three.js의 three/examples/jsm/geometries/TextGeometry.js 모듈을 가져와야 합니다.
또한, 폰트 데이터가 필요하므로 FontLoader를 사용하여 .json 형식의 폰트를 불러와야 합니다.

기본 코드 예제

import * as THREE from 'three';
import { FontLoader } from 'three/examples/jsm/loaders/FontLoader.js';
import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry.js';

// 씬(Scene) 생성
const scene = new THREE.Scene();

// 글꼴 로드
const loader = new FontLoader();
loader.load('fonts/helvetiker_regular.typeface.json', function (font) {
  // 3D 텍스트 생성
  const textGeometry = new TextGeometry('Hello Three.js!', {
    font: font,
    size: 1,       // 텍스트 크기
    height: 0.2,   // 두께 -> 최근 버전에서는 depth로 변경
    curveSegments: 12, // 곡선 품질
    bevelEnabled: true, // 외곽 베벨(Chamfer) 효과
    bevelThickness: 0.03, // 베벨 두께
    bevelSize: 0.02, // 베벨 크기
    bevelOffset: 0,
    bevelSegments: 5  // 베벨 세그먼트 수
  });

  // 재질(Material) 적용
  const material = new THREE.MeshBasicMaterial({ color: 0xff6347 });
  const textMesh = new THREE.Mesh(textGeometry, material);

  // 씬에 추가
  scene.add(textMesh);
});

위 코드에서는 "Hello Three.js!" 라는 3D 텍스트를 생성하고, 빨간색 재질을 적용하여 씬에 추가합니다.

curveSegmentsbevelSegments를 조절해서 성능을 높일 수 있다. 글자 모양이 망가지지 않는 선에서 해당 값을 줄이는 것이 최적화에 도움이 된다.

Bevel(베벨)이란?

Bevel(베벨)은 모서리를 둥글게 다듬거나 깎아서 부드럽게 만드는 효과입니다.
Three.js의 TextGeometry에서 Bevel을 활성화하면 텍스트의 날카로운 모서리를 부드럽게 처리하여 더 자연스럽고 입체적인 느낌을 줄 수 있습니다.


2. TextGeometry의 주요 옵션

속성설명기본값
font사용할 폰트(JSON 형식)-
size텍스트 크기100
height텍스트의 두께 (깊이)50
curveSegments곡선을 얼마나 부드럽게 표현할지 (숫자가 클수록 부드러움)12
bevelEnabled베벨(Chamfer) 효과 활성화 여부false
bevelThickness베벨의 두께10
bevelSize베벨 크기 (외곽선 너비)8
bevelOffset베벨 시작 지점 조정0
bevelSegments베벨의 세부 표현 정도 (값이 클수록 부드러움)3

+ frustum culling vs box bounging

textGeometry.computeBoundingBox()
console.log(textGeometry.boundingBox)
// Box3 인스턴스를 확인할 수 있다.
// min, max 값이 찍히는데, min 프로퍼티는 bevelThickness와 bevelSize 값으로 인해 0이 아닌 마이너스 값이 찍힌다.

화면의 가운데에 mesh를 위치할 수 있다. (bevel 값까지 고려하여 계산하는 것을 잊지 말자)

textGeometry.translate(
	- (textGeometry.boundingBox.max.x - 0.02) * 0.5,
  	- (textGeometry.boundingBox.max.y - 0.02) * 0.5,
 	- (textGeometry.boundingBox.max.z - 0.03) * 0.5,
)

근데 아래의 코드와 동일하다. ㅋ

textGeometry.center()

3. TextGeometry에 Material 적용

TextGeometryMesh 객체에 적용할 수 있으며, 다양한 Material을 사용할 수 있습니다.

(1) 기본 색상 적용

const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
const textMesh = new THREE.Mesh(textGeometry, material);
scene.add(textMesh);

(2) 메탈 재질 적용

const material = new THREE.MeshStandardMaterial({ 
  color: 0xffd700, // 금색
  metalness: 1,    // 금속 느낌
  roughness: 0.3   // 표면 거칠기 조절
});
const textMesh = new THREE.Mesh(textGeometry, material);
scene.add(textMesh);

(3) 와이어프레임(Wireframe) 효과

const material = new THREE.MeshBasicMaterial({ wireframe: true });
const textMesh = new THREE.Mesh(textGeometry, material);
scene.add(textMesh);

(4) matcap 적용

const textureLoader = new THREE.TextureLoader()
const matcapTexture = textureLoader.load('/textures/matcaps/1.png')
matcapTexture.colorSpace = THREE.SRGBColorSpace

const material = new THREE.MeshMatcapMaterial({matcap: matcapTexture})
const textMesh = new THREE.Mesh(textGeometry, material);
scene.add(textMesh);

4. TextGeometry 활용 예제

(1) 회전 애니메이션 추가

function animate() {
  requestAnimationFrame(animate);
  textMesh.rotation.y += 0.01; // Y축 회전
  renderer.render(scene, camera);
}
animate();

(2) 여러 개의 텍스트 배치

const words = ['Hello', 'Three.js', '3D Text!'];
words.forEach((word, index) => {
  const textGeometry = new TextGeometry(word, { font, size: 1, height: 0.2 });
  const textMesh = new THREE.Mesh(textGeometry, new THREE.MeshStandardMaterial({ color: 0x00aaff }));
  textMesh.position.set(index * 3, 0, 0); // X축으로 간격 배치
  scene.add(textMesh);
});

(3) Object 추가

const donutGeometry = new THREE.TorusBufferGeometry(0.3, 0.2, 20, 45)
const donutMaterial = new THREE.MeshMatcapMaterial({ matcap: matcapTexture })
// 밖에서 상수로 관리하니 렌더링 시간이 1/10 이상으로 줄어들었다. 최적화 항상 고려하기!

for (let i = 0; i < 100; i++) {
    const donut = new THREE.Mesh(donutGeometry, donutMaterial)
    donut.position.x = (Math.random() - 0.5) * 10
    donut.position.y = (Math.random() - 0.5) * 10
    donut.position.z = (Math.random() - 0.5) * 10
  
  	donut.rotation.x = Math.random() * Math.PI
    donut.rotation.y = Math.random() * Math.PI
  
 	const scale = Math.random()
    dount.scale.set(scale, scale, scale)
}

5. TextGeometry를 사용할 때 주의할 점

폰트 파일(.json) 필요
Three.js에서는 FontLoader를 사용하여 폰트 데이터를 JSON 형식으로 로드해야 합니다.
(기본적으로 helvetiker_regular.typeface.json 같은 폰트가 제공됨.)

높은 세그먼트 수는 성능 저하 가능
곡선 세그먼트(curveSegments)와 베벨 세그먼트(bevelSegments) 값이 크면 텍스트가 부드러워지지만 성능에 영향을 줄 수 있음.

글자 배치 조정 필요
기본적으로 텍스트 중심이 (0, 0, 0)에서 시작하므로, position.set(x, y, z)를 사용하여 적절히 위치 조정해야 함.


6. 결론

  • TextGeometryThree.js에서 3D 텍스트를 만들기 위한 기하학적 객체입니다.
  • FontLoader를 사용하여 JSON 폰트 파일을 로드해야 합니다.
  • Material을 적용하여 다양한 스타일(금속, 와이어프레임 등)을 표현 가능합니다.
  • 애니메이션 및 배치를 조정하여 인터랙티브한 3D 텍스트 효과를 만들 수 있습니다.
profile
🌙`、、`ヽ`ヽ`、、ヽヽ、`、ヽ`ヽ`ヽヽ` ヽ`、`ヽ`、ヽ``、ヽ`ヽ`、ヽヽ`ヽ、ヽ `ヽ、ヽヽ`ヽ`、``ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ`ヽ`ヽ、ヽ、ヽ`ヽ`ヽ 、ヽ、ヽ、ヽ``、ヽ`、ヽヽ 🚶‍♀ ヽ``ヽ``、ヽ`、

0개의 댓글