読者です 読者をやめる 読者になる 読者になる

VOYAGE GROUP VR室ブログ

VOYAGE GROUP VR室のブログです。コンテンツの紹介や制作方法、イベントレポートなどについて書きます。原則毎週水曜日更新。

A-FrameとHTML Shaderで美しい日本語テキストを表示する方法

A-Frame

こんにちは。家のMacのOSをうっかりSierraに上げた結果、アホほどカスタマイズしてたKarabinerが機能しなくなって生産性が半分くらいになったjujunjun110です。

開発者のみなさんがSierra用に作り直しているようなので、ただただ早期復活を祈るばかり...!頑張れ!

さて、今回もA-Frameの小ネタを紹介していきます。

目次

A-Frameにおけるテキスト

実は、A-Frameにおいて、デフォルトのままでテキストを表示するコンポーネント要素は用意されていません

ただし、有志によっていくつかテキスト表示用のプラグインが作成されておりまして、以下のように公式FAQにまとめられています。

これによると、以下の方法がテキスト表示に利用できるようです。

なのですが、ここに落とし穴が...!

実は、推奨のBitmap Font Text Componentをはじめとして、テキスト専用のプラグインはどれも日本語(マルチバイト文字)に未対応なのです。

さすがにセマンティックウェブの時代にUse Imagesはしたくないので、2016年11月現在時点では日本語テキストを使うには HTML Shaderが最善の選択と思われます。

HTML Shaderとhtml2canvasのインストールと読み込み

HTML Shaderは、その名の通り2次元のDOM要素をマテリアルとして、3次元のA-Frameオブジェクト上に貼り付けることができるロックなコンポーネントです。

テキスト専用のコンポーネントというわけではないので、ウェブ開発に慣れている方ならレイアウトやデザインを簡単にいじれるのも嬉しいところですね!

HTML Shaderはcanvas要素にjavascriptでDOM要素を直接レンダリングするhtml2canvasという、これまたかなりロックなライブラリの上に成り立っているので、これら2つをnpmなどでインストールしたのちヘッダーに読み込んでいきます。

<script src="js/aframe.min.js"></script>
<script src="js/aframe-html-shader.min.js"></script>
<script src="js/html2canvas.min.js"></script>

HTML Shaderの使い方

まず、描画したいHTML要素を<a-scene>要素の前にHTMLで記述します。

<div id="target1" class="target">
    <img src="img/aframe-logo.jpg" alt="A-Frame">
    <div class="cf"><h3>A-Frame</h3>
    <p>A-Frameは簡単にWeb VRが実現できるフレームワークです。</p></div>
    <p class="detail">320px × 200px</p>
</div>

h2ul>li などセマンティックな情報を持ったHTML要素で書けるのも、SEO等の点でなかなか好ましい点ですね。

f:id:jujunjun110:20161115190832p:plain

↑今回はこんな感じにcssを当ててみました。 320px × 200pxは、白くて少し分かりにくいですが親のdiv要素の大きさです。

のちほど描画先を指定するのに利用するため、id="target1"のようにidを振っておきましょう。

次に、シーン内に以下のようにオブジェクトを配置し、以下の2つを指定します。

  • shaderに"html"を指定
  • targetに描画したいHTML要素のidを指定
<a-plane width="16" height="10" material="shader:html;target: #target1;"></a-plane>

A-Frameではデフォルトのもの以外にシェーダーを自作することもできるので、今回はライブラリから読み込んだhtmlという名前のシェーダーを使っているという意味です。


これをブラウザで開くと...

https://media.giphy.com/media/3oriOcU1V8zybeucpO/giphy.gif

VR空間内にHTMLを描画することに成功しました!


なのですが...よく見てみると...

f:id:jujunjun110:20161115191049p:plain

テキストがかなりぼやけてしまっています。

これは、正面から見たときに描画ピクセルごとにぴったりと色が配置されている状態の画像を、斜めから見た状態の見え方にマッピングする際に、元となる方の画像の画素が粗いためうまくマッピングしきれずに色の境界部分がぼやけてしまうという現象が起きていると思われます。

ぼやけ・にじみを直す方法

ということで、綺麗に表示するためにいろいろ試行錯誤したというのが今回のエントリです。

見つけた対処法はシンプルで、元となるHTML要素をかなり大きく作っておくことです。

こうすることで元となる画が細かくなり斜めに見た画像の1ドットを描画するときに、どの色を取得してくればよいかがより明確になるため色の境界がはっきりするということなのだと思います。

では、どれくらい大きなHTML要素を作れば良いのでしょうか。

確かめるために以下のようなサンプルを作ってみました。

(↑ぐりぐりできます)

フルスクリーンでページを閲覧する

githubでソースコードを見る

これは、A-Frame側の実装はそのままに、もととなるDOM要素の大きさを、以下のように変化させてみたものです。

  • 320px × 200px
  • 640px × 400px
  • 960px × 600px
  • 1280px × 800px
  • 1600px × 1000px
  • 3200px × 2000px

f:id:jujunjun110:20161115192340p:plain

いかがでしょうか。

もととなるDOM要素を大きく作れば作るほど、描画されるパネルがくっきりしているのが分かると思います。

個人の感覚によると思いますが、フルスクリーンで見たときに個人的には元となるDOM要素が1600px × 1000px くらいの大きさのパネルだと、かなり満足できるくらいの綺麗さかなと思います。

当然、元のDOM要素が大きければ大きいほど、マッピングの処理を行うWebGLの負荷は大きくなると思われますので、アプリケーション全体の動作を見ながらバランスを取る必要がありそうです。

本当はマルチバイト文字をバッチリ表示してくれるコンポーネントが出来てくれるのが一番なんですけどね!


ということで、今回はA-Frameで日本語を綺麗に表示するTIPSについて更新してみました。

他にもいい方法を見つけた方がいたら、Twitterなどで教えてください!

次回は来週水曜日、DayBySayが素晴らしい何かを更新してくれるものと思います。