WebVR APIと WebGL API によって、ウェブブラウザ内でバーチャルリアリティ (VR) 体験を作成し始めることが可能になっていますが、コミュニティはもっと簡単に作れるツールやライブラリが現れるのを待っています。Mozilla の A-Frame フレームワークは、ウェブ開発者が慣れ親しんでいるシステムを用いて 3D VR 空間を構築するマークアップ言語を提供しています。このシステムはゲーム開発のコーディング原則に従っています; これはプロトタイプやデモを、大量の JavaScript や GLSL を書かずに、迅速にうまく構築するのに役立ちます。この記事では A-Frame をどうやって起動するか、そしてそれをつかって簡単なデモを構築する方法を説明します。
大まかな概要
A-Frame の現在のバージョンは 0.3.2 で、まだまだ実験的な段階ですが、既に動作しており、すぐにブラウザで試すことができます。デスクトップやモバイル (iOS や Android) の Oculus Rift、GearVR、HTC Vive で動作します。
A-Frame は WebGL 上に構築されていて、アプリケーション内で使える構築済みコンポーネント (モデル、ビデオプレイヤー、スカイボックス、ジオメトリ、コントロール、カーソルなど)を持っています。A-Frame は、ゲーム開発業界でよく知られているエンティティ-コンポーネント システム (entity component system)に基づいていますが、マークアップ構造に慣れたウェブ開発者を対象としていて、JavaScript による操作が可能です。つまり、デフォルトで VR-enabled な 3D ウェブ体験となります。
環境設定
A-Frame で何かを作るために環境設定を始めましょう。デモを構築しながら動かしていきます。次のことから始めてください:
- 最新の Firefox やChromeのような WebGL を十分サポートしている最新のブラウザ (もし利用可能な VR ハードウェアがある場合は WebVR をサポートしているブラウザ) を使っているか確認してください — Firefox Nightly または Chrome (v54 以降) をダウンロードしましょう。
- (必要に応じて) Oculus Rift や Google Cardboard のような VR デバイスをセットアップします。
- プロジェクトを保存する新しいディレクトリを作成します。
- そのディレクトリに、最新の A-Frame JavaScript library file (GitHub 最新の安定開発版リポジトリを確認してください) のコピーを保存します。
- 別のタブで A-Frame documentation を開いておきます — 参照するのに便利なので。
HTML 構造
最初のステップは HTML ドキュメントを作成することです — 先程作成したプロジェクトディレクトリの中に、新しく index.html
ファイルを作成して、その中に次の HTML を記述して保存します:
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>MDN Games: A-Frame demo</title>
<script src="aframe.min.js"></script>
</head>
<body>
<!-- HTML goes here -->
</body>
</html>
ドキュメントcharset や
<title>
のような基本的な情報を含んでいます.最初の <script>
要素は A-Frameフレームワークをページにインクルードします; <body>
要素の中にサンプルコードを書いていきます.
シーンの初期化
シーンは、すべてが起こる場所です。このデモでは新しいオブジェクトを作成したら、それら全てをシーンへ追加していきます。そうすることで、それらのオブジェクトがスクリーン上に表示されるようになります。A-Frameの中では、シーンは Scene エンティティ で表現されています。
注記: エンティティは任意の要素です — box や cylinder や cone のようなオブジェクトだけでなく、camera、light、sound sourceもエンティティです。
<body>
要素の内側に <a-scene>
要素を追加してシーンを作成してみましょう:
<a-scene>
</a-scene>
立方体の追加
シーンに立方体を追加するには、単に <a-scene>
要素の内側に <a-cube>
要素を追加するだけです。次のコードを追加します:
<a-cube
color="#0095DD"
position="0 1 0"
rotation="20 40 0">
</a-cube>
いくつかの定義済みパラメータが含まれています: color
、position
、rotation
— かなり分かりやすいと思いますが、立方体の色や 3D シーン内の位置、そして立方体の回転状態を定義しています。
注記: 距離の値 (例えば、立方体のy方向の位置) は単位がなく、シーンに適切と思える好きな単位 — ミリメートル、メートル、フィート、マイル — と考えてください。あなた次第です。
背景の追加: スカイボックス
スカイボックス(sky box) は 3D 空間における背景で、<a-sky>
要素で表現します。このデモでは、単純な背景色を使いますが、画像などを使うこともできます。周りを見回したときに晴れた空なのか、木造の納屋なのか、どんな場所にいるか好きな印象を与えることができます! <a-cube>
要素の直前に次の HTML を追加します:
<a-sky color="#DDDDDD"></a-sky>
ここで、コードを保存してブラウザを更新すると、設定した背景のスクリーン上に立方体が見えるはずです:
ここまでで作ってきたコードは次の通りです:
Github 上で確認することもできます。
A-Frame は必要となるものをすべてセットアップしてくれます:
- デフォルトの光源やカメラが含まれているので、立方体が見えています。
- コントロールも既に動作しています: マウスを使って周りを見回したり、キーボードで移動することができます ( W、A、S、D キーを試してください)。
- VRモードに入る("Enter VR mode") ボタンもスクリーン右下にあり、VR ハードウェアがセットアップされて使える状態になっていれば、ステレオ画面分割されたフルスクリーンモードへ移行できます
カメラの指定
camera エンティティは、 <a-camera>
要素をシーンへ追加することで作成することもできます。カメラの位置を明示的に指定することができ、形状が見えるようにシーンの中心から少しだけ後ろに移動させています。</a-scene>
要素を閉じる前にこれを追加します:
<a-camera
position="0 1 4"
cursor-visible="true"
cursor-scale="2"
cursor-color="#0095DD"
cursor-opacity="0.5">
</a-camera>
cursor-*
属性を使って、カメラにカーソルを設定することもできます (デフォルトは非表示) — 見やすくするためにカーソルのスケールを設定するだけでなく、背後にあるオブジェクトを隠してしまうのを防ぐために色や透明度を設定することもできます。
ライトの追加
A-Frame の基本的な光源タイプは directional と ambient です。最初のタイプはシーン内のどこかに配置された平行光源で、2つ目のタイプは最初のタイプから反射しますのでより自然に見えます; このライトはグローバルにセットできます。新しいコードを既存コードの下に追加します — ここでは標準的な <a-light>
要素を使います:
<a-light
type="directional"
color="#FFF"
intensity="0.5"
position="-1 1 2">
</a-light>
<a-light
type="ambient"
color="#FFF">
</a-light>
directional ライトは白色で、強度を 0.5
にセットし、位置 -1 1 2
に配置しています。ambient ライトは色のみ指定することができ、これも白にしています。
もう少し高度なジオメトリの追加
ここまでにシーンに立方体を追加できました; それでは、もう少し形状を追加してみましょう。<a-cube>
のようなデフォルトエンティティに制限されているわけではありません — <a-entity>
を用いて、独自の複雑な形状を作成することができます。トーラスを追加してみましょう — 次の要素を既存コードの下に追加します:
<a-entity
geometry="
primitive: torus;
radius: 1;
radiusTubular: 0.1;
segmentsTubular: 12;"
rotation="10 0 0"
position="-3 1 0">
</a-entity>
ここで追加したエンティティは トーラス プリミティブで、トーラス形状を表します。形状に幾つかの初期値を与えています: トーラスの外側エッジの半径、チューブの半径、チューブの円周方向の分割数をそれぞれ指定します。回転と位置は、今までに見てきたものと同様にセットしました。
マテリアルの定義
シーンにトーラスが表示されましたが、色があまり良くありません — エンティティの見た目を定義するにはマテリアル(材質) を作成する必要があります。 <a-entity>
を次のように編集して、トーラスの見た目を定義します:
<a-entity
geometry="
primitive: torus;
radius: 1;
radiusTubular: 0.1;
segmentsTubular: 12;"
material="
color: #EAEFF2;
roughness: 0.1;
metalness: 0.5;"
rotation="10 0 0"
position="-3 1 0">
</a-entity>
新しく追加した material
属性では、マテリアルの color
と、 roughness
(表面の粗いマテリアルは、滑らかなマテリアルよりも反射光の方向が散らばります)、metalness
(マテリアルがどの程度金属っぽいか) をセットしています。
mixのための JavaScript の追加
JavaScript で作成したエンティティをシーンへ追加することもできますので、その機能を使って3つ目の形状として円柱を追加してみましょう。<body>
要素の最後、つまり <a-scene>
の直後に、新たに <script>
要素を追加し、その内側に次の JaveScript コードを記述します:
var scene = document.querySelector('a-scene');
var cylinder = document.createElement('a-cylinder');
cylinder.setAttribute('color', '#FF9500');
cylinder.setAttribute('height', '2');
cylinder.setAttribute('radius', '0.75');
cylinder.setAttribute('position', '3 1 0');
scene.appendChild(cylinder);
最初にシーンハンドラへの参照を取得して、A-Frame エンティティの1つである cylinder 要素を作成します。あとはすべて適切な属性の設定です: 色 color
、高さ height
、半径 radius
、位置 position
。最後の行では、新しく作成した円柱をシーンへ追加しています。それだけで — 3つの異なる形状を A-Frame で作成できました! 次のように見えているはずです:
数行の HTML と JavaScript でこのようなシーンが作成できてしまうなんて素晴らしいですね。
アニメーション
rotation
や position
を使ってシーン上の形状を動かしてきましたが、拡大縮小をすることもできます。アニメーションするイリュージョンを作成するためにこれらの属性を操作できます。
回転
要素をアニメーションさせるのに便利な、特別な <a-animation>
エンティティがあります。<a-animation>
要素を <a-cube>
要素の子として、次のように追加します:
<a-cube
color="#0095DD"
rotation="20 40 0"
position="0 1 0">
<a-animation
attribute="rotation"
from="20 0 0"
to="20 360 0"
direction="alternate"
dur="4000"
repeat="indefinite"
easing="ease">
</a-animation>
</a-cube>
他のエンティティでも同様に、アニメーション用のキープロパティを定義できます。ここでは rotation
属性を 20 0 0
から 20 360 0
へとアニメーションさせているので、1周回転することになります。アニメーションの方向(direction)は、alternate に設定されているため、順方向(forward)にアニメーションが再生されます。継続時間(duration)を 4 秒に、そして繰り返し(repeat)がずっと続く(indefinite)ように設定してします。アニメーションの easing は ease
を使っています。これは内部的に実装されている tween.js によって実行されます。
拡大縮小
エンティティのアニメーションは、このデモで使ったトーラスのようなカスタムジオメトリにも同じように追加することができます。次に示す <a-animation>
要素をトーラスへ追加します:
<a-entity
geometry="
primitive: torus;
radius: 1;
radiusTubular: 0.1;
segmentsTubular: 12;"
material="
color: #EAEFF2;
roughness: 0.1;
metalness: 0.5;"
rotation="10 0 0"
position="-3 1 0">
<a-animation
attribute="scale"
to="1 0.5 1"
direction="alternate"
dur="2000"
repeat="indefinite"
easing="linear">
</a-animation>
</a-entity>
このトーラスをアニメーションさせる対象の属性は scale
です。初期のデフォルトスケールは 1 1 1
で、それを 1 0.5 1
にアニメーションさせていますので、 y
軸が 1
から 0.5
へスケールが変化します。easing には linear
を使っています。direction を alternate
にセットすることで、2秒かけてスケールが 0.5
へ変化したあと 1
へと戻ります。再度、repeat は indefinite を指定して無限に繰り返す設定にしています。
移動
render()
関数を使って,シリンダの位置を毎フレーム更新します - Y軸の値を変更でき,移動にどんな効果がでるか見てみましょう.
3つ目の形状の位置(position)をアニメーションさせるのに <a-animation>
を使うこともできますが、ここではその代わりに JavaScript を使ってみましょう。このコードを <script>
タグの末尾に追加します:
var t = 0;
function render() {
t += 0.01;
requestAnimationFrame(render);
cylinder.setAttribute('position', '3 '+(Math.sin(t*2)+1)+' 0');
}
render();
円柱の位置を毎フレーム更新するために render()
関数を使っています。y
軸に与える値を変更して、それが移動にどんな影響をあたえるか試してみてください。
最後に
すべて適切にレンダリングされてアニメーションしていますね — おめでとう、あなたの最初の A-Frame シーンが構築できました! 最終版がどのように見えて、どのように動くかは、ここで確認できます:
利用可能な VR デバイスを持っていれば、それを使ってあなたのシーンを試す良いタイミングです。
注記: Github で確認することもできます。
思っていたよりも簡単だったでしょう? A-Frame はウェブ開発者を対象に、ウェブマークアップの容易さや、JavaScript 操作のような利点を取り込んでいます。簡単に始められて、その上、先進的なコンセプトの強力なAPIも提供しています。 as well as dealing with cross browser differences and suchlike. コミュニティも、ちょうどサポートする VR デバイスの数のように広がっています — このフレームワークで実験を始めるにはちょうどよい機会です。