みかづきブログ・カスタム

基本的にはちょちょいのほいです。

Three.jsのTextGeometryで日本語を立体的に表示する 🇯🇵


ソースコード抜粋

// three.js r127 にて検証
const fontLoader = new THREE.FontLoader(); // ローダーのインスタンスをつくる

fontLoader.load('/scripts/m-plus-1-code-bold.json', (font) => { // typeface.jsを読み込む
  const textGeometry = new THREE.TextGeometry('ステーキハウス', {
    font: font,
    size: .2,
    height: .2
  });

  textGeometry.center();

  const textMaterial = new THREE.MeshNormalMaterial();
  const text = new THREE.Mesh(textGeometry, textMaterial);

  scene.add(text);
});

基本的に難しいことはなかったです。

  • fontLoaderで日本語フォントのtypeface.jsを読み込む
  • textGeometryのfontにfontLoaderの引数を渡す

でOKでした。


typeface.jsの入手方法

Google Fonts から日本語のフォントを探してダウンロードし、ttfファイルを こちらのサイト で変換しました。

gero3.github.io

typeface.jsで検索した時に先頭に出てきたからです。

www.google.com


はまったところ

僕は M PLUS 1 Code をダウンロードして使わせてもらったのですが、当初は Noto Sans Japanese を使おうと思っていました。

fonts.google.com

しかし、Noto Sans Japaneseをダウンロードしたところ、otfファイルしか入っておらず、otfファイルを こちらのサイト で変換して使ってみたところ、

THREE.BufferGeometry.computeBoundingSphere(): Computed radius is NaN. The "position" attribute is likely to have NaN values.

というエラーが出たので、諦めてttfファイルがダウンロードできるフォントに切り替えました。
oftファイルだからうまくいかなかったのか、Noto Sans Japanese固有の問題かは追っていません。


r136への対応

その後、Three.jsをr136に変更したところ、

THREE.FontLoader has been moved to /examples/jsm/loaders/FontLoader.js

THREE.TextGeometry has been moved to /examples/jsm/geometries/TextGeometry.js

と2箇所エラーがでました。
FontLoaderとTextGeometryがTHREE直下ではなく、別ファイルに分かれたことが原因です。

// three.js r136 にて検証
import { FontLoader } from '~/examples/jsm/loaders/FontLoader';
import { TextGeometry } from '~/examples/jsm/geometries/TextGeometry';

const fontLoader = new FontLoader(); // THREE.FontLoaderから変更

fontLoader.load('/scripts/m-plus-1-code-bold.json', (font) => {
  const textGeometry = new TextGeometry('ステーキハウス', { // THREE.TextGeometryから変更
    font: font,
    size: .2,
    height: .2
  });

  textGeometry.center();

  const textMaterial = new THREE.MeshNormalMaterial();
  const text = new THREE.Mesh(textGeometry, textMaterial);

  scene.add(text);
});

という感じでモジュールを読み込むことで対応できました。