Three.jsでテキストを空間に表示する方法は、大きく分けて2種類あります。1つは画像を生成してMaterialを使ってメッシュ表面に表示する方法、もう一つは、ShapeのGeometryを生成する方法です。
今回は、shapeのGeometryを生成する方法と、文字を形成するのに必要なFontのJSONデータの生成方法から、データを軽量化するサブセット化の方法を解説いたします。
テキストの生成方法
ShapeのGeometryでのテキスト生成の詳細は、公式サンプルから参照お願いします。
three.js exampleshttps://threejs.org/ three.js/examples/webgl_geometry_text_shapes.html at master · mrdoob/three.jsJavaScript 3D Library. Contribute to mrdoob/three.js development by creating an account on GitHub.
JSONデータ化
ShapeのGeometry生成に必要なFontのJSONデータを作成します。
今回は、Google FontsからZen Old Minchoを使います。右上のGET Fontからフォントデータのzipファイルをダウンロードします。

フォルダ内の.ttf「ZenOldMincho-Regular.ttf」を、JSONデータにコンバートします。
下記のfacetype.jsのサイトを使用させていただきます。
https://gero3.github.io/facetype.js/ Facetype.jsFacetype.js : typeface.js generator
ファイルを選択から、変換したい.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水準漢字など
以下のサイトが、非常に綺麗にまとめられています。ご参照ください。
U-618WEB WEB関係のメモ。 日本語WEBフォントをサブセット化する際の参考文字列一覧 | U-618WEBWEBフォントをサブセット化して使用する際に参考になるかもしれない文字列一覧です。 Noto sansの軽量化
ひらがな・カタカナ
ぁあぃいぅうぇえぉおかがきぎくぐけげこごさざしじすずせぜそぞただちぢっつづてでとどなにぬねのはばぱひびぴふぶぷへべぺほぼぽまみむめもゃやゅゆょよらりるれろゎわゐゑをん
ァアィイゥウェエォオカガキギクグケゲコゴサザシジスズセゼソゾタダチヂッツヅテデトドナニヌネノハバパヒビピフブプヘベペホボポマミムメモャヤュユョヨラリルレロヮワヰヱヲンヴヵヶ英字・数字
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
0123456789
abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ
0123456789
!"#$%&'()-^\@[;:],./\=~|`{+*}<>?_記号
、。,.・:;?!゛゜´`¨^ ̄_ヽヾゝゞ〃仝々〆〇ー―‐/\~∥|…‥‘’“”()〔〕[]{}〈〉《》「」『』【】+-±×÷=≠<>≦≧∞∴♂♀°′″℃¥$¢£%#&*@§☆★○●◎◇◆□■△▲▽▼※〒→←↑↓〓∈∋⊆⊇⊂⊃∪∩∧∨¬⇒⇔∀∃∠⊥⌒∂∇≡≒≪≫√∽∝∵∫∬ʼn♯♭♪ΑΒΓΔΕΖΗΘΙΚΛΜΝΞΟΠΡΣΤΥΦΧΨΩαβγδεζηθικλμνξοπρστυφχψωАБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯабвгдеёжзийклмнопрстуфхцчшщъыьэюя─│┌┐┘└├┬┤┴┼━┃┏┓┛┗┣┳┫┻╋┠┯┨┷┿┝┰┥┸╂。「」、・ヲァィゥェォャュョッーアイウエオカキクケコサシスセソタチツテトナニヌネノハヒフヘホマミムメモヤユヨラリルレロワン゙゚①②③④⑤⑥⑦⑧⑨⑩⑪⑫⑬⑭⑮⑯⑰⑱⑲⑳ⅠⅡⅢⅣⅤⅥⅦⅧⅨⅩ㍉㌔㌢㍍㌘㌧㌃㌶㍑㍗㌍㌦㌣㌫㍊㌻㎜㎝㎞㎎㎏㏄㎡ ㍻〝〟№㏍℡㊤㊥㊦㊧㊨㈱㈲㈹㍾㍽㍼≒≡∫∮∑√⊥∠∟⊿∵∩∪参照サイトから、「JIS第1水準+常用漢字+その他」などをコピーして、必要な文字列をサブセットメーカーに格納して、作成できます。
JSONデータ化
再びのfacetype.jsのサイトを使って、サブセットメーカーで作成したFontデータ.ttfをJSONデータ化してダウンロードします。
https://gero3.github.io/facetype.js/ Facetype.jsFacetype.js : typeface.js generator
ファイルを選択から、サブセットメーカーで作成したFontデータ.ttfを選び、ConvertしてJSONデータをダウンロードします。
「JIS第1水準+常用漢字+その他」で、9.1MBになりました。元のJSONデータ21.9MBより、約58%削減されました。
完成
いかがだったでしょうか。
初音ミク・プログラミングコンテストで使用したテクニックで、備忘録を兼ねてブログにいたしました。JSONデータが非常に大きくなってしまう問題に直面したときに、サブセット化することでなんとか解決しました。サイトのデータが重いと、離脱率が上がってしまう原因になります。ぜひ、ご使用の際は、参考にしていただけると幸いです。


