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;
Last updated