Experts.jp日本に、もっとエキスパートを。(3)今回のサンプルの完成版。VRでパノラマ写真を見るというコンテンツを作成しました。サンプルを試していただいた方は「なんか結構できたじゃん感」を満喫できたと思います。それもそのはず、360度写真のみのコンテンツは、天球にパノラマ画像を貼り付けた時点で、目的の99%を達成できたといえるからです。ほとんど完成といっていい状態でしょう。他のVRコンテンツを触ったことがある人間なら、少しもの足りなさを感じることと思います。一つはインタラクティブ性のなさ、そしてもう一つはモノの存在感のなさです。インタラクティブ性のなさは、イベント駆動型のVRコンテンツの作成というハードルが待っていますが、今回はそれはさておき、モノの存在感について書いていきます。パノラマ画像だけで構成された世界は、「一見、目の前で展開されている感じなのに、触ることができないほど遠くに広がる世界」と言えます。目の前の芝生に近付いて触ることはできませんし、奥の人に近付くこともできません。仮に頑張って、インタラクティブ性を高めて奥に進めるように作ったとしても、そこにあるのは拡大されて画素が粗くなった人のようなナニカでしかありません。VRのモノとしての存在を確固たるものにするために大事なことは、VR空間に実際にモノを置いてみるということになります。VRに用意されているコンポーネントのうち、モノとして置けるコンポーネント、3Dプリミティブについて扱っていきます。Componentsの目次は下記のような構成になっています。AmbientLightBoxLiveEnvCameraCylinderCylindricalPanelDirectionalLightModelPanoPlanePointLightSceneSoundSphereSpotLightVideoVideoControlVideoPanoVrButtonいろいろありますね。「あれ?、これだけしかないの?」という見方もあるかもしれません。主要なものを役割ごとにカテゴライズしてみましたので順に見ていきましょう。VRリポジトリのViews以下を見てみるとよいでしょう。空間を作るタイプのコンポーネントまず、チェックしておきたいのは空間を作るタイプのコンポーネントです。VideoPanoCylindricalPanelPanoPanoは、既に登場しましたが、360度写真をVR空間に貼り付けるタイプのコンポーネントです。VideoPanoは、Panoと同様ですが、貼り付け可能コンテンツが360度動画となります。CylindricalPanelは、ちょっと特殊なコンポーネントで、内側にテクスチャを貼ることができ、子コンポーネントを収録できるタイプです。ビデオ・オーディオ関連のコンポーネントビデオの話が少し出ましたが、ビデオ・オーディオ系に関係してくるコンポーネントは以下となります。SoundVideoSoundは、シーンに配置するコンポーネントですが、何か形があるわけではありません。音の発生源として配置する形になります。3Dオーディオをサポートしており、ヘッドマウントディスプレイを被って顔を左右に振ったりすると、音源の場所に応じたサウンドになることが確認できます。Videoは、2Dのビデオを再生するためのコンポーネントです。これをユーザーの前面に貼ると巨大なテレビが目の前に広がったような演出ができます。ユーザーインターフェースとなるコンポーネント続いて、VR世界のユーザーインターフェースとなるコンポーネントが下記2つです。VrButtonVideoControlVrButtonは、ボタンです。応用性が高く、使い勝手の良いコンポーネントと言えるでしょう。VideoControlは、ビデオをコントロールするためのユーザーインターフェースとなります。VideoコンポーネントとVideoControlコンポーネントを組み合わせると、VR空間にビデオプレーヤーを作ることができます。Videoコンポーネントでビデオを表示させているサンプル形状コンポーネントそして、今回扱う形状コンポーネントです。BoxCylinderPlaneSphereModel上記のうち、Modelを除いた4つは3Dプリミティブコンポーネントと呼ばれます。Boxは立方体や直方体などを作成することができるタイプのコンポーネントです。Cylinderは、円筒形の形状コンポーネントで、設定によっては円錐形の形状を作成することができます。Planeは、フラットな平面コンポーネントです。ちなみに、Modelは空間に配置するコンポーネントだけど、別の3Dソフトなどで作成したモデルデータを使用するためのもので、今回は一旦スキップします。これ以外にもライティングに関するコンポーネントも存在しますが、実際に使うところで解説していきます。今回は実際に3Dプリミティブコンポーネントを、シーンにいろいろと配置し、様々なライティングをしてみましょう。3Dプリミティブコンポーネントを配置してみようさて、これから3Dプリミティブコンポーネントを配置していろいろ実験していくわけですが、その前に、何か仮想現実の実験ぽくするための会場づくりをしましょう。VRで何も背景に敷かない場合、漆黒の空間に単なる立方体が浮かぶことになります。それでは何も趣がないですよね。いうことで、VR空間をホロデッキ(アメリカのTVドラマ・映画のスタートレックに登場するホログラフィックルーム)として定義してみましょう。ホロデッキってなあに?って方は、Wikipediaのホロデッキに関する説明と写真をご覧ください。ホロデッキは、黒い部屋に、方眼紙のような感じで黄色の線が入っている部屋です。これを実現するためにPanoコンポーネントを使います。Panoコンポーネントは360度写真を閲覧するために前回使いましたが、Panoコンポーネントはもう一つ使い方があって、6つのテクスチャを配列で渡してあげると、立方体のの内側にテクスチャが貼られた部屋を作ることができます。VRプロジェクトを作成するところから始めてみましょう。VRプロジェクトを作成し、Panoコンポーネントで部屋を作るまずはなにはともあれ、新規ReactVRプロジェクトを立ち上げましょう。名前はHello3DObjectとしましょう。Hello3DObject続いて、Panoコンポーネントを使って、テクスチャが貼られた立方体の空間を作っていきます。プロジェクトルートにある「index.vr.js」のViewコンポーネント以下を編集していきます。今回Panoコンポーネントの内側には、前後左右上下の6面にテクスチャを貼ります。Patternsのうち一枚をPhotoShopで修正した格子状のものです。ホロデッキっぽいテクスチャ画像こちらからダウンロードください上記リンク先でダウンロードしたファイルを解凍し、中に入っている「holodeck.png」を「static_assets」ディレクトリ以下に配置します。Panoコンポーネントに対して六面にテクスチャを貼るには、source属性にuriプロパティを持ったオブジェクトを6つ含んだ配列を渡します。パス名}の形式で返るので、asset関数をそのままsource属性へ渡せばいいことになります。前]}/></View>さて、まずはここで一旦ビルドしてみましょう。startブラウザで、http://localhost:8081/vr/を開いてみましょう。スタートレックのホロデッキのような空間が出現したと思います。テクスチャのつなぎ目とか細かい点はサンプルということでご容赦ください。Boxをいくつか並べて配置してみるホロデッキ的な空間が出来たところで、Boxコンポーネントを配置してみましょう。Boxコンポーネントはシンプルなコンポーネントですが、よくありがちな失敗として、Boxコンポーネントをインポートし忘れるということがあります。これから登場するCylinderやSphereも同様にimportし忘れがないようにしましょう。'react-vr';では、Boxコンポーネントを目の前に3つ配置してみます。Panoコンポーネントの下にBoxコンポーネントを下記のように3つ記述します。-2]}],}}lit={false}/></View>dimWidth、dimHeight、dimDepthの各属性は、幅、高さ、奥行きのサイズに相当します。この比率を変えることで、立方体や柱のようなもの、平らな板のようなものを作り出すことができます。style属性で色が定義されていることもわかります。3つの色は右から青、赤、緑の原色です。style属性にtransformというプロパティが定義されていますが、ここで配置を指定しています。位置関係の変形は、translateで指定します。配列で指定し、左からX座標、Y座標、Z座標となります。ちなみにマイナスの数値になればなるほど初期状態の位置から奥へ向かって移動する形になります。litという属性がありますが、こちらはライティングに関するプロパティで、後ほど解説します。Boxだけでなく、CylinderやSphereを配置してみるさて、今度はCylinderやSphereもシーンに配置してみます。Boxコンポーネントのパートで作った3つのボックスは消してしまいましょう。勢いあまってホロデッキっぽくしているPanoまで消さないようにしてくださいね、情感がなくなってしまいますので。Cylinderコンポーネントについて。Cylinder、つまりカタカナでいうシリンダーは、円筒を意味しますが、Cylinderコンポーネントはプロパティ次第で円錐形にもなります。ポイントはradiusTopとradiusBottomで、radiusTopが小さければ山のようになっていき、radiusBottomが大きければ、ラッパのような形状になっていきます。どちらの値も等しい時だけ円筒形になります。続いてSphereコンポーネントですが、Sphereというのは球体です。Sphereコンポーネントはなかなか使い出があるコンポーネントで、四角形や円筒形を使う機会はそれほどないかもしれませんが、球体というのはテクスチャを貼り付ければ惑星になったりと応用性が高い3Dプリミティブコンポーネントです。下記のようにシーンに配置してみました。それぞれ一つずつ配置しています。SphereコンポーネントにはwidthSegmentsとheightSegmentsというプロパティがありますが、これは球体を構成するセグメント(分割数)を定義しています。この数が増えるとなめらかな球体へ近づいていきます。-5]}],}}lit={false}/></View>今回、ちょっと配置に工夫をしています。translateプロパティの値を変更していて、手前に立方体、奥に行くにしたがって円筒形、球体と並ぶようにしています。これで3Dプリミティブの配置は完了したわけですが、何かもの足りません。していて立体感がないのです。いうことで、この3Dオブジェクトに光を当てていきましょう。VRでライティング(照明)を行うには、用意されている4つのコンポーネントのいずれかもしくは複数の組み合わせを使用します。VRコンポーネントは下記の4つです。AmbientLightDirectionalLightPointLightSpotLightAmbientLightは、環境光と呼ばれるもので、シーン全体に均一な影響を与える光源を定義します。これは無指向性で、すべてのオブジェクトが等しく明るくなります。DirectionalLightは、指向性があるが、距離による明かりの減光は発生しないタイプの光源です。太陽の明かりのようなものと言えます。PointLightは、ある一点から発生する光源で、距離による減光もあります。見えない間接照明のようなものと言えるでしょう。SpotLightは、文字通りスポットライトのような特性を持つととらえられる光源です。指向性があり、距離による範囲の拡大と減光があります。VRが使用しているThree.jsにおいても手厚いサポートがされていること、そしておそらくはこうしたライティング関係は、カスタムコンポーネントとしての作成が困難であろうことなどが推測されます。普通の光を当てましょう。太陽のように上から降り注ぐ普通の明かりです。いった明かりは、DirectionalLightコンポーネントを使うことで実現できます。準備段階として、先ほど作成した3種類の3Dプリミティブオブジェクトが持っているlitプロパティをtrueにしてみましょう。これで光源の影響を受けるようになります。試しにtrueにした段階で、ブラウザをリロードしてみてください。光が当たっていないため、真っ黒のオブジェクトになってしまったと思います。真っ黒の3Dプリミティブオブジェクト続いて、DirectionalLightコンポーネントを配置します。Panoコンポーネントの下あたりでOKです。/></View>intensityプロパティは、光の強度を設定します。光源にも色をつけることができ、スタイルシートで定義します。transformプロパティでrotateXの設定をしていますが、これは、ちょっと斜め前方から光を当てたいからです。本当の真上からあたる光は、側面すら陰になってしまい、あまり面白みはありません。DirectionalLightを設定したシーン次はPointLightコンポーネントを配置してみましょう。PointLightは点光源なので、任意の位置に配置すると、その周囲を照らしてくれます。うまく使うと印象的な効果を与えることができます。今回は、PointLightをちょっと手前に配置し、しかもちょっと青系の光として照らしてみましょう。どんな感じになるでしょうか。DirectionalLightコンポーネントの下に、下記のようにPointLightコンポーネントを設置します。/></View>intensityプロパティはちょっと強めの5にしました。色は青色、そして位置はちょっと手前でちょっと下から照らす感じにしています。すると、こんな感じで、青い光がオブジェクトに反射するような雰囲気になりました。ムーディで怪しげですね。PointLightを反映させた3Dプリミティブオブジェクトさて、これで終了にしてもいいのですが、全体的にちょっと暗いですよね、そこで光の調整をしたいと思います。AmbientLightコンポーネントを配置してみましょう。AmbientLightは環境光で、全てのオブジェクトに均等に光を当てるという機能を持っています。AmbientLightコンポーネントを使うことで、全体的な光の加減を微調整することもできます。/></View>intensityプロパティは、ほんの少しだけ設定しました。これでブラウザをリロードしてみると、ほんのりと明るくなったことがわかると思います。AmbientLightを反映させた3Dプリミティブオブジェクトいろいろな形状のものを置き、ライティングを終えたところで、こんな風に思った方はいないでしょうか。「現実世界で立方体や球なんて、積み木とかにしか存在しないじゃないか!」と。VRで扱う方法について解説していきます。