【Three.js】How to display Japanese text (Shape version) + subsetting to lighten font JSON data

Three.js

Three.jsでテキストを空間に表示する方法は、大きく分けて2種類あります。1つは画像を生成してMaterialを使ってメッシュ表面に表示する方法、もう一つは、ShapeのGeometryを生成する方法です。

今回は、shapeのGeometryを生成する方法と、文字を形成するのに必要なFontのJSONデータの生成方法から、データを軽量化するサブセット化の方法を解説いたします。

テキストの生成方法

ShapeのGeometryでのテキスト生成の詳細は、公式サンプルから参照お願いします。

three.js examples
three.js/examples/webgl_geometry_text_shapes.html at master · mrdoob/three.js
JavaScript 3D Library. Contribute to mrdoob/three.js development by creating an account on GitHub.
https://threejs.org/

JSONデータ化

ShapeのGeometry生成に必要なFontのJSONデータを作成します。

今回は、Google FontsからZen Old Minchoを使います。右上のGET Fontからフォントデータのzipファイルをダウンロードします。

フォルダ内の.ttf「ZenOldMincho-Regular.ttf」を、JSONデータにコンバートします。

下記のfacetype.jsのサイトを使用させていただきます。

Facetype.js
Facetype.js : typeface.js generator
https://gero3.github.io/facetype.js/

ファイルを選択から、変換したい.ttf「ZenOldMincho-Regular.ttf」を選び、ConvertしてJSONデータをダウンロードします。

JSONデータが、21.9MBと非常に重たいですが、あとでサブセット処理するので軽量化できます。

Three.jsで文字を表示する

import { FontLoader } from 'three/addons/loaders/FontLoader.js';
import Typeface from '../static/ZenOldMincho_Regular.json'; // FontのJSONデータ


// Three.js でテキストを生成するために必要なフォントデータ
const fontLoader = new FontLoader();
const Ffont  = fontLoader.parse(Typeface);

~~

class ObjectText{
  // コンストラクター
  constructor(string) {
    this.string = string;

    this.material = new THREE.MeshBasicMaterial({
      color: 0x222222,
      side: THREE.DoubleSide,
      transparent: true,
      wireframe: false,
    });
  }

  //メソッド Fillテキスト
  CreatObject(){
    const TEXT = this.string;
    const shapes = Ffont.generateShapes( TEXT, 4 );//文字サイズ
    const TextGeometry = new THREE.ShapeGeometry( shapes, 4 );
    TextGeometry.computeBoundingBox();
    TextGeometry.center();//Center the geometry based on the bounding box.

    const Geotext = new THREE.Mesh( TextGeometry, this.material );
    
    //中央に表示する
    Geotext.name = "SongText";
    scene.add(Geotext);
  }

}

const myObject = new ObjectText("あいうえお");
myObject.CreatObject();

先ほどダウンロードしたフォントのJSONデータを読み込んで、文字を生成して表示させます。

Fontのサブセット化

JSONデータが、21.9MBと非常に重たいかったので、「必要な文字だけ」or「ひらがな・カタカナ」などにする方法を紹介します。

サブセット化するには、武蔵システムさんのフリーソフト「サブセットフォントメーカー」が必要です。以下から、インストールお願いします。

サブセットフォントメーカー
サブセットフォントメーカー

サブセットメーカーにある「フォントに格納する文字(C)」に必要な文字を入力することで、その文字だけのフォントファイル.ttfを書き出します。

必要な文字だけを書き出す

文章などのテキストデータを集めて、Stringに格納することで、重複している文字を削除してくれるコードです。ここで、出力された文字列をサブセットメーカーに格納することで、OKです。

const String = `ここに対象の文字データを入れる`;

function removeDuplicates(String) {
  const uniqueCharacters = new Set(String);
  return [...uniqueCharacters].join('');
}

const result = removeDuplicates(String);
console.log(result); // 出力
    ```

ひらがな・カタカナ・JIS第1水準漢字など

以下のサイトが、非常に綺麗にまとめられています。ご参照ください。

日本語WEBフォントをサブセット化する際の参考文字列一覧 | U-618WEB
WEBフォントをサブセット化して使用する際に参考になるかもしれない文字列一覧です。 Noto sansの軽量化
U-618WEB WEB関係のメモ。

ひらがな・カタカナ

ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをん
ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ

英字・数字

ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789
 !"#$%&'()-^\@[;:],./\=~|`{+*}<>?_

記号

  、。,.・:;?!゛゜´`¨^ ̄_ヽヾゝゞ〃仝々〆〇ー―‐/\~∥|…‥‘’“”()〔〕[]{}〈〉《》「」『』【】+-±×÷=≠<>≦≧∞∴♂♀°′″℃¥$¢£%#&*@§☆★○●◎◇◆□■△▲▽▼※〒→←↑↓〓∈∋⊆⊇⊂⊃∪∩∧∨¬⇒⇔∀∃∠⊥⌒∂∇≡≒≪≫√∽∝∵∫∬ʼn♯♭♪ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя─│┌┐┘└├┬┤┴┼━┃┏┓┛┗┣┳┫┻╋┠┯┨┷┿┝┰┥┸╂。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ㍉㌔㌢㍍㌘㌧㌃㌶㍑㍗㌍㌦㌣㌫㍊㌻㎜㎝㎞㎎㎏㏄㎡ ㍻〝〟№㏍℡㊤㊥㊦㊧㊨㈱㈲㈹㍾㍽㍼≒≡∫∮∑√⊥∠∟⊿∵∩∪

参照サイトから、「JIS第1水準+常用漢字+その他」などをコピーして、必要な文字列をサブセットメーカーに格納して、作成できます。

JSONデータ化

再びのfacetype.jsのサイトを使って、サブセットメーカーで作成したFontデータ.ttfをJSONデータ化してダウンロードします。

Facetype.js
Facetype.js : typeface.js generator
https://gero3.github.io/facetype.js/

ファイルを選択から、サブセットメーカーで作成したFontデータ.ttfを選び、ConvertしてJSONデータをダウンロードします。

「JIS第1水準+常用漢字+その他」で、9.1MBになりました。元のJSONデータ21.9MBより、約58%削減されました。

完成

いかがだったでしょうか。

初音ミク・プログラミングコンテストで使用したテクニックで、備忘録を兼ねてブログにいたしました。JSONデータが非常に大きくなってしまう問題に直面したときに、サブセット化することでなんとか解決しました。サイトのデータが重いと、離脱率が上がってしまう原因になります。ぜひ、ご使用の際は、参考にしていただけると幸いです。

初音ミク「マジカルミライ 」 プログラミング・コンテスト
プログラミングの力で創作文化に参加できる!初音ミク「マジカルミライ 2024」プログラミング・コンテストを実施!
タイトルとURLをコピーしました