22sook00 logo
SookDev
🪐

Three.js 텍스트 효과

tag
3d
date
Jan 24, 2024

01_Text typeface

우리가 일반적으로 사용하는 ttf, otf 형식이 아닌, Three.js 에서 제공하는 타입페이스 라는 제이슨 형태이다.
typeface 를 import 하면 꽤 많은 폰트를 json 형태로 지원하는것을 볼 수 있다.
하지만 한글은 지원하지 않아서 우리가 일반적으로 사용하는 폰트를 타입페이스로 변환하는 작업이 필요하다.
Facetype.js 라는 컨버터 라이브러리를 통해 쉽게 변환할 수 있다.
notion image
폰트를 import 하는 방식은 두가지가있다.
import { FontLoader } from "three/examples/jsm/loaders/FontLoader"; //font const fontLoader = new FontLoader(); fontLoader.load( "./asset/fonts/LINE Seed Sans KR Bold_Regular.json", (font) => { console.log("load", font); }, (event) => { console.log("progress", event); }, (error) => { console.log("error", error); } ); //폰트경로 ,콜백함수,불러오는 과정콜백까지 로그를 찍고 상세지정 가능
fontLoader 만 import 하여 인스턴스를 생성하여 폰트경로를 지정하는 방식과
parse 메소드는 객체 자체를 자바스크립트에서 직접 불러오고 그 객체를 three.js 에서 이해할 수 있는 형식으로 파싱하는 방법이다.
import typeface from "./asset/fonts/LINE Seed Sans KR Bold_Regular.json"; const font = FontLoader.parse(typeface);

02_텍스트 장면에 추가하기

TextGeometry 의 다양한 속성들에 대해 알아본다.

ExtrudeGeometry

글자의 날카로운 부분을 부드럽게 변경해주는 속성이다.
notion image
ExtrudeGeometry 의 bevelSegments 는 경사진 면을 몇개의 레이어로 나눌것인가를 정하는것인데,
많아질수록 경사진 변이 좀 더 부드럽게 표현이 가능하다.
하지만 무작정 크게 설정하면 성능적으로 문제가 있을 수 있기 떄문에 적절하게 사용 할 필요가 있다.
notion image
 

Texture

구글에 텍스처만 검색해도 상당히 많은 재질의 이미지가 나타나다.
그 중 홀로그램 느낌의 재질로 테스트를 해보려고 한다.
TextureLoader 메소드를 이용하여 텍스처를 load 할 수 있다.
const textureLoader = new THREE.TextureLoader().setPath("./asset/textures/"); const textTexture = textureLoader.load("holographic.jpeg"); textMaterial.map = textTexture;

Spotlight

글자의 조명을 비춰주는 손전등 효과가 있는 속성이다.
notion image
const spotLight = new THREE.SpotLight( 0xffffff, 3, //빛의 강도 30, //빛이 닿는 거리 Math.PI * 0.15, //빛이 퍼지는 각도 0.2, //빛이 감소하는 정도 0.5 //거리에따라 빛이 어두어지는 양 ); spotLight.position.set(0, 0, 3); scene.add(spotLight);
spotLightHelper 속성을 이용하여 카메라의 위치를 돌려가며 본다면
하나의 점 형태에서 원뿔형태로 빛이 번져나가는것을 볼 수 있다.
notion image
gui 툴 이용하여 하나씩 조절해보기
const spotLightFolder = gui.addFolder("SpotLight"); spotLightFolder .add(spotLight, "angle") .min(0) .max(Math.PI / 2) .step(0.01); spotLightFolder .add(spotLight.position, "z") .min(1) .max(10) .step(0.01) .name("position.z"); spotLightFolder.add(spotLight, "distance").min(1).max(30).step(0.01); spotLightFolder.add(spotLight, "decay").min(1).max(10).step(0.01); //빛의 거리에 따라 빛이 희미해지는 정도를 나타낸다. spotLightFolder.add(spotLight, "penumbra").min(0).max(1).step(0.01);
 

02_텍스트 애니메이션

마우스 인터렉션에 따라 텍스트 애니메이션 효과주기
js 의 mousemove 메소드를 통해 e.clientX,e.clientY 좌표값을 찍어면 특정 값들이 나온다.
하지만 이는 절대적인 좌표값이기 때문에 three.js 가 받아들이는 위치와 달라져버려서 먼 위치에 좌표계가 위치해버린다.
이 좌표값을 각각 윈도우창의 전체높이와 전체너비에 대한 상대적인 값으로 변경하기 위해
각각 innerWidth 와 innerHeight 으로 나눠준다.
const spotLight = new THREE.SpotLight( 0xffffff, 3, //빛의 강도 30, //빛이 닿는 거리 Math.PI * 0.15, //빛이 퍼지는 각도 0.2, //빛이 감소하는 정도 0.5 //거리에따라 빛이 어두어지는 양 ); spotLight.position.set(0, 0, 3); spotLight.target.position.set(0, 0, -3); scene.add(spotLight, spotLight.target); //마우스 인터렉션에 따른 텍스트애니메이션 window.addEventListener("mousemove", (e) => { const x = (e.clientX / window.innerWidth - 0.5) * 5; //-0.5 를 하는 이유는 왼쪽으로가면 -, 오른쪽으로 이동하면 + 처리 하기위함. const y = -(e.clientY / window.innerHeight - 0.5) * 5; // *5 를 하는 이유는 범위를 5배수만큼 더 크게 설정하기 위함. //현재 마우스의 위치를 계산해서 스팟 라이트의 타겟포지션을 해당값으로 설정해주면 된다. spotLight.target.position.set(x, y, -3); });

빛에 의한 그림자 추가하기

castShadow() 와 receiveShadow()
그림자는 발생되는 곳에서 보내주는 그림자, 평면(plane)에서 받을 그림자 두개를 지정하면 된다.