PlayStation 4でVR(仮想現実)を体験できるPlayStation VRの発売が目前に迫り、いよいよVRが一般家庭へ普及し始めると話題になってます。以前ICS MEDIAでもWebのテクノロジーを使用してVRコンテンツを作成する方法を記事「WebGLではじめるお手軽VR入門」で紹介し、反響をいただきました。
今回は、Webのテクノロジーだけで、かつプログラムも使わずVRコンテンツの作成に挑戦する方法を紹介します。なんと、JavaScriptをかくことなくHTMLにタグを追加するだけでVRコンテンツが作成できるんです!
次のデモは実際に作成したVRコンテンツです。中央の円状のカーソルを牛の3Dモデルに重ねることでアニメーションします。詳しい作成方法は本記事の後半で解説します。
※パソコンではドラッグ、スマートフォンではジャイロセンサーが検知した傾きで視点が変わります。右下のアイコンをクリックすると、HMDで閲覧できるモードへ切り替わります。
HTMLをマークアップするようにVRコンテンツを作成しよう
VRコンテンツをHTMLのマークアップのように作成するには、JavaScriptライブラリ「A-Frame」を使用します。「やっぱりJavaScriptを使うのか」と思うかもしれませんが、HTMLからこのライブラリを読み込むだけで、VRコンテンツに必要な処理を用意してくれます。
▲A-Frameを使用して作られたVRコンテンツの事例。A-FrameのGitHubページより引用
A-Frameは、MozillaのVRチームが開発したWebVRフレームワークです。WebVRとは、WebブラウザからOculus RiftなどのHMD(ヘッドマウントディスプレイ)へVRコンテンツを出力する仕組みのことです。このWebVRを採用することで、Webのテクノロジーで作成したVRコンテンツをHMDで体験できるようになります。HMDを持っていない方でも、記事「WebGLではじめるお手軽VR入門」で紹介したGoogle Cardboardとスマートフォンがあれば体験できます。
▲Google Cardboard
▲Google CardboardでVRコンテンツを体験している様子
A-Frameを使用したVRコンテンツの作り方をデモを交えて紹介
A-Frameを使用したVRコンテンツの作り方を6つのオリジナルデモで紹介します。本記事では、A-Frameの基本的な使いかたの解説となるため、詳しいことを知りたい方はA-Frameの公式ドキュメントページをご覧ください。
A-Frameを使うための下準備
1. ライブラリのダウンロード
A-FrameのGitHubページからライブラリをダウンロードします。GitHubページの右上にある[Clone or download]ボタンをクリックし、その中から[Download ZIP]をクリックします。すると、ライブラリのデータが入ったZipファイルがダウンロードされるので、任意の場所に展開します。
2. HTMLからライブラリを読み込む
展開したaframe-master
フォルダー内のdist
フォルダーにaframe-v0.3.0.min.js
というJavaScriptファイルがあるので、作業する任意の場所に格納します。そのJavaScriptファイルを、次のようにHTMLから読み込むだけで準備完了です。
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="UTF-8"> <!-- A-FrameのJavaScriptファイルを読み込みます --> <script src="../assets/js/aframe-v0.3.0.min.js"></script> </head> <body> <!-- A-Frameのタグを記述します --> </body> </html>
ボックスを配置するデモ
3D空間(シーン)にボックスを配置するデモです。A-Frameでは、シーンにオブジェクトを追加することでコンテンツを作っていきます。
このデモは3種類の要素をbody
要素内に記述するだけで実現できます。まず始めに、3Dを描画するシーンをa-scene
要素で追加します。その中にa-box
要素(ボックス)とa-sky
要素(背景)を追加すると3D空間に表示されます。
<body> <!-- シーン --> <a-scene> <!-- ボックス --> <a-box position="0 0.5 -1.5" rotation="0 45 0" width="1" height="1" depth="1" color="#e67e22"></a-box> <!-- 背景 --> <a-sky color="#fafafa"></a-sky> </a-scene> </body>
a-box
要素のposition
属性でXYZ軸方向の座標、rotation
属性でXYZ軸方向の回転角度、width
属性で幅、height
属性で高さ、depth
属性で奥行き、color
属性で色を設定します。
<!-- ボックス --> <a-box position="0 0.5 -1.5" rotation="0 45 0" width="1" height="1" depth="1" color="#e67e22"></a-box>
a-sky
要素でシーンのcolor
属性で背景色を設定します。
<!-- 背景 --> <a-sky color="#fafafa"></a-sky>
ボックスにテクスチャーを設定するデモ
「ボックスを配置するデモ」で配置したボックスにテクスチャーを設定するデモです。
A-Frame内で外部ファイルを使用するときはa-assets
要素内に追加していきます。a-assets
要素内に追加した外部ファイルを使用する場合は、オブジェクトのsrc
属性で参照します。
<body> <!-- シーン --> <a-scene> <!-- アセット --> <a-assets> <img id="texture" src="../assets/images/texture.jpg"> </a-assets> <!-- ボックス --> <a-box src="#texture" position="0 0.5 -1.5" rotation="0 45 0" width="1" height="1" depth="1"></a-box> <!-- 背景 --> <a-sky color="#fafafa"></a-sky> </a-scene> </body>
a-scene
要素内にimg
要素でテクスチャーの画像ファイルを追加します。img
要素のid
属性でオブジェクトから参照時に使用するID、src
属性で画像ファイルのファイルパスを設定します。
<!-- アセット --> <a-assets> <img id="texture" src="../assets/images/texture.jpg"> </a-assets>
a-assets
要素内に追加したテクスチャーをボックスに反映します。a-box
要素のsrc
属性に、テクスチャーIDの先頭に#
をつけた文字列を設定します。
<!-- ボックス --> <a-box src="#texture" position="0 0.5 -1.5" rotation="0 45 0" width="1" height="1" depth="1"></a-box>
3Dモデルを配置するデモ
3Dモデルをシーンに配置するデモです。3Dモデルのファイルフォーマットには、多くの3Dモデリング・レンダリングソフトでサポートされているOBJ形式を使用します。
<body> <!-- シーン --> <a-scene> <!-- アセット --> <a-assets> <!-- 3Dモデルデータ --> <a-asset-item id="cow-obj" src="../assets/obj/spot_quadrangulated.obj"></a-asset-item> <!-- マテリアルデータ --> <a-asset-item id="cow-mtl" src="../assets/obj/spot_quadrangulated.mtl"></a-asset-item> </a-assets> <!-- 3Dモデル --> <a-entity obj-model="obj: #cow-obj; mtl: #cow-mtl" position="0 1 -1.5" rotation="0 135 0"></a-entity> <!-- 背景 --> <a-sky color="#fafafa"></a-sky> </a-scene> </body>
A-FrameでOBJ形式の3Dモデルを配置するには、3DのモデルデータであるOBJファイルと、マテリアル(オブジェクト上の質感)のデータであるMTLファイルが必要です。a-scene
要素内にa-asset-item
要素として追加します。
<!-- アセット --> <a-assets> <!-- 3Dモデルデータ --> <a-asset-item id="cow-obj" src="../assets/obj/spot_quadrangulated.obj"></a-asset-item> <!-- マテリアルデータ --> <a-asset-item id="cow-mtl" src="../assets/obj/spot_quadrangulated.mtl"></a-asset-item> </a-assets>
3Dモデルの描画にはa-entity
要素を使用します。obj-model
属性にobj: #cow-obj
で3Dモデルデータを、mtl: #cow-mtl
でマテリアルデータを設定します。
<!-- 3Dモデル --> <a-entity obj-model="obj: #cow-obj; mtl: #cow-mtl" position="0 1 -1.5" rotation="0 135 0"></a-entity>
アニメーションを設定するデモ
「3Dモデルを配置するデモ」で配置した3Dモデルにアニメーションを設定します。
<body> <!-- シーン --> <a-scene> <!-- アセット --> <a-assets> <!-- 3Dモデルデータ --> <a-asset-item id="cow-obj" src="../assets/obj/spot_quadrangulated.obj"></a-asset-item> <!-- マテリアルデータ --> <a-asset-item id="cow-mtl" src="../assets/obj/spot_quadrangulated.mtl"></a-asset-item> </a-assets> <!-- 3Dモデル --> <a-entity obj-model="obj: #cow-obj; mtl: #cow-mtl" position="0 0.5 -1.5" rotation="0 180 0"> <a-animation attribute="rotation" dur="5000" to="0 540 0" repeat="indefinite"></a-animation> </a-entity> <!-- 背景 --> <a-sky color="#fafafa"></a-sky> </a-scene> </body>
a-entity
要素内にa-animation
要素を追加してアニメーションを設定します。attribute
属性でアニメーションさせる属性(ここでは角度させたいためrotation
)、dur
属性でアニメーションの再生時間、to
属性でアニメーションの目標値、repeat
でアニメーションのリピート回数(ここではループし続けたいためindefinite
)を設定します。
<a-animation attribute="rotation" dur="5000" to="0 540 0" easing="ease-in-out-back" repeat="indefinite"></a-animation>
背景に全天球画像を設定するデモ
シーンの背景に全天球画像を設定するデモです。背景を単色から全天球画像へ差し替えるだけでグッと没入感が増します。
<body> <!-- シーン --> <a-scene> <!-- アセット --> <a-assets> <!-- 3Dモデルデータ --> <a-asset-item id="cow-obj" src="../assets/obj/spot_quadrangulated.obj"></a-asset-item> <!-- マテリアルデータ --> <a-asset-item id="cow-mtl" src="../assets/obj/spot_quadrangulated.mtl"></a-asset-item> <!-- 全天球画像 --> <img id="sky" src="../assets/images/puydesancy.jpg"> </a-assets> <!-- 3Dモデル --> <a-entity obj-model="obj: #cow-obj; mtl: #cow-mtl" position="0 1 -2" rotation="0 180 0"> <a-animation attribute="rotation" dur="5000" to="0 540 0" repeat="indefinite"></a-animation> </a-entity> <!-- 全天球背景 --> <a-sky src="#sky" rotation="0 -130 0"></a-sky> </a-scene> </body>
a-assets
要素内に全天球画像を追加します。
<!-- アセット --> <a-assets> // 略 <!-- 全天球画像 --> <img id="sky" src="../assets/images/puydesancy.jpg"> </a-assets>
a-sky
要素のsrc
属性でa-assets
要素内に追加した全天球画像を設定します。
<!-- 全天球背景 --> <a-sky src="#sky" rotation="0 -130 0"></a-sky>
VRコンテンツを操作するUIの実装するデモ
VRコンテンツは視界が奪われてしまうため、キーボードやマウスでの操作は向いてません。そのため、視界の中央にカーソルを配置し、そのカーソルが一定時間とどまったところをアクティブ状態と判断するといったVR独特なUIの実装が必要になります。
<body> <!-- シーン --> <a-scene> <!-- アセット --> <a-assets> <!-- 3Dモデルデータ --> <a-asset-item id="cow-obj" src="../assets/obj/spot_quadrangulated.obj"></a-asset-item> <!-- マテリアルデータ --> <a-asset-item id="cow-mtl" src="../assets/obj/spot_quadrangulated.mtl"></a-asset-item> <!-- 全天球画像 --> <img id="sky" src="../assets/images/puydesancy.jpg"> </a-assets> <!-- カメラ --> <a-camera> <!-- カーソル --> <a-entity cursor="fuse: true; fuseTimeout: 1000"> <!-- リング --> <a-ring color="#e74c3c" radius-inner="0.01" radius-outer="0.015" position="0 0 -0.75"></a-ring> </a-entity> </a-camera> <!-- 3Dモデル --> <a-entity obj-model="obj: #cow-obj; mtl: #cow-mtl" position="0 0.5 -3" rotation="0 180 0"> <a-animation begin="click" attribute="rotation" dur="5000" to="0 540 0"></a-animation> </a-entity> <!-- 全天球背景 --> <a-sky src="#sky" rotation="0 -130 0"></a-sky> </a-scene> </body>
カーソルを常に視界の中央に配置するには、カメラと結びつける必要があります。a-scene
要素にa-camera
要素を追加し、その中にカーソルとなるa-entity
要素を追加します。a-entity
要素のcursor
属性にfuse: true
でカーソルを有効、fuseTimeout: 1000
でアクティブと判断するまでの時間(ここでは1000ミリ秒=1秒)を設定します。
<!-- カメラ --> <a-camera> <!-- カーソル --> <a-entity cursor="fuse: true; fuseTimeout: 1000"> <!-- リング --> <a-ring color="#e74c3c" radius-inner="0.01" radius-outer="0.015" position="0 0 -0.75"></a-ring> </a-entity> </a-camera>
このデモでは、3Dモデルがアクティブになったらアニメーションが始まるようにするため、a-animation
要素のbegin
属性にclick
を指定します。
<a-animation begin="click" attribute="rotation" dur="5000" to="0 540 0"></a-animation>
最後に
今回紹介したデモよりも複雑なVRコンテンツの作成には、JavaScriptでガッチリと実装する必要がありますが、スマートフォンのジャイロセンサーの機能を使って空間をぐるぐる見渡したいコンテンツなどには充分ではないでしょうか。
今まではJavaScriptが得意でない方にはなかなか手が出せなかったWebVRですが、これを期に挑戦してみてはいかがでしょうか。ここぞというときのネタの1つとなれれば幸いです。