🎥

A-Frameで日本語フォントを使う

2024/07/31に公開

※本記事は終了した別サービスで2020年4月13日に公開した記事のリストアで、スライドの簡易版です。

はじめに

現在、A-Frameには標準で日本語フォントがありません。<a-text>タグのvalueに日本語を記述しても文字化けします。自前でMSDF(multi-channel signed distance fonts)形式のフォントファイルを用意して、<a-text>タグのfont属性やfont-image属性にセットする必要があります。

MSDFは、ttf(TrueTypeFont)などから作成しますが、日本語フォントは巨大なこともあり、けっこうめんどくさいです。
そこで作成済みのフォントをいくつか用意して公開しました。

aframe-japanese-font

このnpmパッケージを解説します。

アプローチ

MSDFの生成方法

MSDFを生成するオンラインのジェネレーターがありますが、日本語は巨大になります。漢字を一通りカバーしようとすると、エラーになります。

そこで、コマンドラインツール版を使いローカルで実行します。

msdf-bmfont-xml

A-Frame専用に出力するために、msdf-bmfont-xmlのラッパーを用意

msdf-bmfont-xmlをカスタマイズしてnode-msdf-generatorを作りました。
主にやってることです。

  • pngファイルを1つにする(<a-text>がマルチパートをサポートしていないため)
  • 日本語種類を定数としてパラメータ化する(平仮名/片仮名/常用漢字/人名漢字)

漢字は、常用漢字(約2100文字)人名漢字(約860文字)を用意しています。

日本語フォント種類

webフォント から引っ張ってきました。今は3種類です。

  1. Noto Sans(ゴシック体)
  2. M+ FONTS(ゴシック体)
  3. ふい字(丸文字)
  • すべてライセンスはクリアしている認識ですが、もし万が一不備などありましたらご指摘いただければ幸いです。
  • NotoSansとふい字のttfで一部の文字が用意できていないっぽくて抜け落ちています。M+フォントは全て作成できています。
  • 抜け落ちた文字はこのログファイルで確認できるようにしています。
    フォントのビルドログ

使い方

実ファイルについて

いちおうnpmパッケージ化しているけど、msdfファイルはクソでかいです。なにせ3000文字以上のテクスチャファイルですから。

npm publishした時のログです。

npm notice 435.2kB fonts/hui/hui-msdf.json
npm notice 531.9kB fonts/mplus/mplus-msdf.json
npm notice 432.7kB fonts/noto-sans-cjk-jp/noto-sans-cjk-jp-msdf.json
npm notice 9.3MB   fonts/hui/hui-msdf.png
npm notice 7.2MB   fonts/mplus/mplus-msdf.png
npm notice 6.9MB   fonts/noto-sans-cjk-jp/noto-sans-cjk-jp-msdf.png

組み込み方法

そもそもnpmインストールしたところで、これらはアセットファイルです。jsファイルにrequire/importするようなものではありません。

ですので、基本的には直接ダウンロードして公開フォルダに格納しましょう。必要なファイルは、aframe-japanese-fontfontsディレクトリ下に各フォント毎に置いている[fontName]-msdf.json[fontName]-msdf.pngの2つです。

その2つのファイルをheadタグなどでインクルードします。A-Frameを通常のjsアプリに組み込んでいる場合は、A-Frameが必要になったところでフォントファイルもダイナミックインポートするといいでしょう。

描画

A-Frameの<a-text>タグのfont属性とfont-image属性に利用したいフォント種類をセットしてvalue属性にテキストを記載すれば、OKです。

<a-scene>
  <a-text
    value="こんにちは世界!"
    font="noto-sans-cjk-jp-msdf.json"
    font-image="noto-sans-cjk-jp-msdf.png"
    negate="false"
    scale="2 2 1"
    position="0 1 -4"
  >
  </a-text>
</a-scene>

Discussion