Text

Text Geometry

Text Geometry를 생성할 때 사용할 폰트 정보를 함께 전달해주어야 한다.

이 때 전달하는 폰트의 형식은 ttf, otf 같은 형식이 아닌 typeface라는 JSON 형식의 폰트를 전달 해야한다

import { TextGeometry } from 'three/examples/jsm/geometries/TextGeometry';

const geometry = new TextGeometry('Hello Words', {
    font: font, // 사용할 폰트
    size: 80, // 폰트 사이즈 (default: 100)
    height: 5, // 텍스트 돌출 두께 (default: 50)
    curveSegments: 12, // 곡선의 세그먼트 수 (default: 12)
    bevelEnabled: true, // bevel(경사)을 컨트롤 할지 여부 (default: false) 
    bevelThickness: 10, // 경사진 면의 두께 (default: 10)
    bevelSize: 8, // 텍스트 윤곽선에서 경사진 면이 얼마나 멀리 떨어져 있는지 (default: 8)
    bevelOffset: 0, // 텍스트 윤곽선에서 경사진 면이 시작되는 거리 (default: 0)
    bevelSegments: 5, // 경사진 면을 몇개의 레이러로 나눌것인지,많은수록 부드러워진다. (default: 3)
  });

Bevel

그래픽 디자인과 3D 모델링에서 사용되는 용어로, 경사진 면을 뜻하며 객체 또는 텍스트의 가장자리를 부드럽게 꺾거나 둥글게 만들어 각진 모서리를 부드럽게 처리할 수 있다.

  • Bevel과 관련된 속성들은 TextGeometry의 상위 클래스 extrudeGemtery에서 지원되는 속성들이다.

Three.js Built In Font

// Three.js에서 기본적으로 제공되는 폰트들은 아래 경로에 서 찾아볼 수 있다.
import typeface from 'three/examples/fonts/'

기본적으로 내장된 폰트들은 한글이 지원되지 않는다.

한글을 지원하는 폰트를 사용하거나, 제공하지 않는 폰트를 사용하고 싶은 경우

  • 일반적으로 사용되는 폰트 파일(ttf, otf 등)을 typeface 형식으로 변환 해주어야 한다.

  • Facetype.js 로 일반 폰트를 typeface로 변환해보자.

  • 폰트를 불러 올 때 Three.js에서 내장된 FontLoader 클래스를 이용

    • 폰트를 불러오는 방법으로는 2가지 방법이 있다.

import { FontLoader } from 'three/examples/jsm/loaders/FontLoader';

const fontLoader = new FontLoader(); 

눈누 사이트를 통해 무료로 폰트를 다운 받을 수 있다. (라이선스 확인 필수)

#1 load('file path', onLoadedCb, onProgressCb, onErrorCb)

폰트 경로를 기입하여 불러오는 메서드

  • 첫 번째 인자로 불러올 폰트 파일 경로를 입력

  • 두 번쨰 인자로 폰트 로드가 완료되는 시점에 호출될 콜백을 입력

    • 불러온 폰트를 통해 textGeometry를 생성하고 scene에 추가해주는 작업을 작성

  • 세 번째 인자로 폰트가 로드되는 동안 실행될 콜백을 입력

  • 네 번째 인자로 폰트 로드되는 동안 에러가 발생하면 실행될 콜백을 입력

fontLoader.load('./assets/The Jamsil OTF 3 Regular_Regular.json', (font) => {
    const textGeometry = new TextGeometry('헬로 월드', {
      font,
      size: 0.5,
      height: 0.1,
    });
    const textMaterial = new THREE.MeshPhongMaterial({ color: '#0066ff' });
    const text = new THREE.Mesh(textGeometry, textMaterial);

    scene.add(text); 
  });

loadAsync()

load() 메서드는 콜백 함수로 비동기 코드를 작성하게되는데 코드가 자칫 더러워질 수 있다. (에러처리, 콜백지옥)

좀 더 깔끔한 코드와 스코프를 맞추기 위해 loadAsync() 메서드를 사용해보자.

  • load() 메서드와 기본적으로 사용방법이 동일하지만, 로드된 폰트를 받아서 사용하는 부분만 다르다.

  • 해당 함수 자체가 Promise를 반환하기에 await 키워드를 필요로 한다. (동기식으로 작성할 경우)

  • 모두 같은 스코프로 되어 있어 값에 접근하기 쉬워진다.

  const font = await fontLoader.loadAsync(
    './assets/Yeongdeok Snow Crab_Regular.json'
  );
  const textGeometry = new TextGeometry('왜이러니', {
    font,
    size: 0.5,
    height: 0.1,
  });
  const textMaterial = new THREE.MeshPhongMaterial({ color: 0x00c896 });
  const text = new THREE.Mesh(textGeometry, textMaterial); 
  scene.add(text);

#2 parse(typeface)

typeface json 객체를 임포트하여 THREE.js에서 이해할 수 있는 형식으로 파싱해주는 메서드

  • 첫 번째 인자로 typeface 객체를 넣어 THREE.js에서 이해할 수 있는 폰트로 반환

  • 반환된 폰트를 textGeometry 를 생성할때 사용

import typeface from '...' 

const font = fontLoader.parse(typeface);

Text Align Center

렌더링된 텍스트를 보면 전체적으로 오른쪽으로 치우쳐저 보인다.

텍스트가 차지하는 너비만큼 X축으로 빼주면 가운데 정렬이 된다.

BoundingBox

BoundingBox란 TextGeometry 경계 영역을 감싸고 있는 박스

  • 기본적으로 계산 되어지지 않기 때문에 .computeBoundingBox() 호출하여 명시적으로 설정 해주어야 한다.

const textGeometry = new TextGeometry('왜이러니', {
    font,
    size: 0.5,
    height: 0.1,
  }); 
textGeometry.computeBoundingBox();
console.log(textGeometry.boundingBox);
// 로그에 찍힌 boundingBox 데이터는 하기와 같다.
// Box3 {isBox3: true, min: _Vector3, max: _Vector3}
// isBox3: true
// max: _Vector3 {x: 2.7249999046325684, y: 0.5299999713897705, z: 0.10000000149011612}
// min: _Vector3 {x: 0.02850000001490116, y: -0.11299999803304672, z: 0}
  • boundingBox의 max.x(끝점)에서 min.x(시작점)을 빼주면 textGeometry 영역의 너비를 계산할 수 있다.

  • 즉, 계산된 너비값의 절반을 X축에서 빼주면 가운데 정렬이 된다.

  • textGeometry의 축 이동은 translate()를 이용

const { min, max } = textGeometry.boundingBox;
textGeometry.translate(
  -(max.x - min.x) * 0.5,
  -(max.y - min.y) * 0.5,
  -(max.z - min.z) * 0.5
);  // x, y, z

center()

단순히 가운데 정렬이 목적이라면 center() 메서드로 간단히 동일한 결과를 얻을 수 있다.

 textGeometry.center();

Texture 추가하기

gemoetry의 표면을 어떤 이미지로 덮는다는 의미

  • TextureLoader()를 이용하여 텍스쳐를 추가하는데 폰트를 불러오는 방법과 비슷하다.

  • 한 가지 다른점은 loadAsync 를 사용하지 않아도 텍스쳐를 반환해준다.

  • 반환된 텍스쳐를 textMaterial의 map 속성에 넣어주면 적용된다.

const textureLoader = new THREE.TextureLoader().setPath('./assets/textures/);
const textTexture = textureLoader.load('holographic.jpeg');
textMaterial.map = textTexture;

TextureLoader.setPath()를 설정하면 텍스쳐 파일들의 베이스 경로를 지정하여 사용할 때 파일이름만 입력해도 동일하게 사용할 수 있다.

Last updated