2014年06月18日

Unity での日本語描画 その1

標準的に用意されている方法は、TextMeshGUI Text の2つのようだ。
どちらもイマイチ。

ある程度の大きさのテクスチャをフォントキャッシュとして、必要な文字を順次書き出し、そこから板ポリに貼り付けて文字を表示していくと言うのが一般的な文字描画の方法だと思う。
が、Unity だとテクスチャを動的に書き換えるのは重くて使い物にならないと言う話だ。
UnityでTexture2Dへの描画は厳禁

Unity の機能ではなく各プラットフォームごとに書き換えるようにすれば、実用的な速度になるようだ。
その用途に以下のものがある。

unity-sysfont ( GitHub )

動的に作るのではなく、事前に用意した文字テクスチャを作る方法として Bitmap font generator を使う方法も。
参考 : その1 NGUI:ビットマップフォント表示~フォントテクスチャを作る

ただ、日本語の場合は文字数が多いので事前準備するとなるとテクスチャが何枚も必要になる。
動的書き換えが遅いと言っても、リアルタイムでの話だろうから、シーンの切れ目でこれから使うフォントテクスチャを動的に使うと言う手も考えられる。

PCFフォントを使って動的にテクスチャに書いていく方法を考えていたが、どうも遅いらしいと言うことで断念。
ちなみにPCFフォントファイルは、otf2bdf で TreeType フォントをテキスト形式のビットマップフォントに変換、bdftopcf で bdf からバイナリの pcf ビットマップフォントに変換できる。
コマンドで使う文字やサイズなども指定できるので、なかなか良さげだ。
まあ、今回はあまり使えなさそうだが。

全部決め手に欠ける。
unity-sysfont が一番良さそうだが、プラットフォームごとにプラグイン切り替えてと言う部分が少し引っかかる。

つづく。

投稿者 Takenori : 21:50 | トラックバック

2014年06月19日

Unity での日本語描画 その2 テクスチャ仮想多重化

2048x2048 のサイズのテクスチャで 64x64 サイズのフォントを入れようとしたら入るのは 1024個。
少し少ない。
32x32 サイズなら 4096個なので、実際に使用されている文字に限定すれば入りそうだ。
JIS 第一水準、第二水準漢字を入れようと思ったら、6355文字必要になる。
英数字も加えるともう少し増える。
これが入る限界サイズは 25x25 辺り。

出来れば 64x64 サイズくらいで詰め込みたいところ。
1ビットアルファとして、文字を詰め込めば 8192 文字入る。
ただ、単純に1ビットで敷き詰めるとシェーダーで取り出すのは困難なので、8層あるとみなして詰め込む。
つまり、最上位1ビットだけ使って 2048x2048 の中に文字を並べ、次に2ビット目に~と並べていく。
するとこんな感じのファイルが出来る。

glyph_20140619.png

アルファに重なっているのでそのままでは読み取れない。
これをシェーダーで取り出す。
ビット演算が使えれば楽だけど、シェーダーバージョン次第で使えないようなので四則演算で取り出す。
最下位ビットは以下の形で取り出せる。

int alpha = int(texcol.a*255.0);
int c0 = alpha / 2;
int c1 = c0 * 2;
int bit = alpha - c1;
texcol.a = float(bit);

アルファ値が 1 か 0 で取得可能。
2ビット目が欲しければ、alpha を最初に2で割る。
以降2の累乗値で割れば、任意ビット位置のアルファ値が得られる。
描画してみるとこんな感じ。

unity_font_20140619.png

補間はまだ書いてないが、後は補間処理を書いて、板ポリゴンに貼り付けるようにしていけば文字描画できるようになる。
PC なら 24 ピクセルくらいになるだろうから、補間でアンチエイリアスがかかった文字になり綺麗に見える。
高繊細ディスプレイなら 64 以上のピクセル数になると思うが、そこそこ綺麗に見えるのではないかと思う。

後、この方法を用いればパレット形式のテクスチャも使えそうだ。
RGBA の各チャンネルでインデックス指定、テクスチャの1ライン目にパレット格納と言う形にすれば、4面分使える。
パレット形式をシェーダーで問題なく使えるか後日試そうと思う。

投稿者 Takenori : 23:11 | トラックバック

 
Total : Today : Yesterday :