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

VR 研究記

3D技術の経験を活かして、VRに挑戦するおっさんの奮闘記

VR美術館の試作にて光源の描画問題ではまった件

VR向けの美術館とは

現在、VR向けの美術館として照明と絵画で演出を工夫しながら考えています。
以下の写真は、開発中のスクリーンショットになります。
f:id:subrutm:20161105055540p:plain

照明としては、2タイプを使っていました。
タイプ1. 全体的に照らす天井の照明
タイプ2. 絵画を照らすための照明

問題点は、ある条件のときにタイプ2の照明が描画されない問題が発生した。
f:id:subrutm:20161105060506p:plain

※表示は、スクリプトで作成しているので、照明の条件はすべて同じです。

解決するには、優先順位を高くしろ!

Lightの設定にある【Render Mode】を【Important】にすると改善します。
f:id:subrutm:20161105061156p:plain

C#スクリプトでは、以下のようにアクセスします。

Lightの構成が、写真の通りだとする。
f:id:subrutm:20161105061817p:plain

using UnityEngine;
using System.Collections;

public class ImageLight : MonoBehaviour {

    // Unity GUIで設定を変更するLightオブジェクト(spotlight)をリンクする
    public Light imageLight;

    // Use this for initialization
    void Start () {
        // Render Modeを変更する [Important (ライトは、常にピクセル単位で描画される)]
        imageLight.renderMode = LightRenderMode.ForcePixel;
    }
}

Light周りで困ったときは、お試しください。

Unityで画面を切り替える方法

Unityで画面を切り替える方法が変わりました。

5.2.Xと最新の5.4.Xでシーンの切換え方法に大きな変更があった事が自分で作り込んでて判明したので情報共有するために記載します。
シーンファイルは、*.unityという拡張子のファイルとして存在しています。

Unity 5.2.Xのシーン切換え方法

using UnityEngine;
using System.Collections;

public class SceneChanger : MonoBehaviour {

        public String nextScene;

	// Use this for initialization
	void Start () {
	}
	
	// Update is called once per frame
	void Update () {
        if (Input.anyKey) {
            Application.LoadLevel(nextScene);
        }
    }
}

Unity 5.4.Xのシーン切換え方法

using UnityEngine;
using System.Collections;

using UnityEngine.SceneManagement;

public class SceneChanger : MonoBehaviour {

        public String nextScene;

	// Use this for initialization
	void Start () {
	}
	
	// Update is called once per frame
	void Update () {
        if (Input.anyKey) {
            SceneManager.LoadScene(nextScene);
        }
    }
}

nextSceneには、次に表示するシーンのファイル名(*.unityの*の部分)を入力すれば良いです。
シーンの切換えトリガーを【if (Input.anyKey)】としてますが、ここは任意です。
コード例の場合は、何かキーを押したらシーンを切り替えると言う意味です。

勉強やテストで作った3D作品とこれから創るVR作品を紹介します♪

・勉強のために書籍を参考にしつつ、材料を利用して作った作品

 

 SFチックな侍の単純に動き回れるアクションゲーム

ムービーですが、asset Storeから得たデータを使って自力で作った最初のアプリです。

https://www.facebook.com/subru.matsuoka/videos/1092863707428841/

 書籍を参考にUnityの機能を活用して作ったシューティングゲーム

 

素材は、書籍からとAsset Storeからの2種類です。
エフェクトなどは、アレンジしてます。
レーダーは、プレーヤーと敵との相対距離を算出して自機から位置関係を表示しています。
また、向きについては自機の方向をそのままZ軸回転させているだけです。

敵から迎撃を受けてます。

f:id:subrutm:20161030182249j:plain

 

ダメージ受けているのですが、危険レベルまで減ってしまって赤くなっているところです。 (中間色として、黄色もあります。)

f:id:subrutm:20161030182250j:plain

 

プレイヤーが攻撃しているところです。

f:id:subrutm:20161030182251j:plain

 

・これから企画として創ろうとしている作品

 VR美術館

VRを使った、絵画鑑賞の空間を作ります。
スポットライトを使った雰囲気の演出などを工夫して、絵画を飾り一人称カメラで実際に擬似空間を散策しながら参照する流れです。

部屋のようなダンジョンにも応用できるので、部屋のような空間での当たり判定や演出効果の学習を兼ねたプロジェクトです。

 

外観です。

f:id:subrutm:20161030183803p:plain

 

内装です。

f:id:subrutm:20161030182853p:plain

 

VRスーパーマリオブロス

学生時代でもやっていたマリオの模擬作品です。
VRを使ってマリオになりきろう!という想いから発足したプロジェクトです。
下準備としてブロックを設置してみただけの画像ですが、今後拡張していきますので開発途中のノウハウなどを公開するのでお楽しみに。

完成したら、遊んでみましょうw

f:id:subrutm:20161030183445p:plain


最後まで、読んで頂きありがとうございました。

 

Oculus APIについて

Oculus APIとデバイスバージョンの関係

  OculusのダウンロードページよりDL出来るAPI(Application Platform Interface)のこと。
私が、試験的に使用していたのはOculus DK2(以後、DK2とする)です。
正式版との違いは、トラッキングバイスに相違がある点です。

あとは、ドライバーも違っているようで、最新のドライバではDK2をコントロールする事は出来ませんでした。

開発言語は、C++, Unity(C#, Java Script), Unreal Engine(C++)に対応しています。

■Oculus DK2の開発環境

OS ドライバ バージョン SDKバージョン Unity Package Version
Windows Oculus Runtime for Windows v0.4.3-beta Oculus SDK for Windows v0.4.3-beta *1 Unity v4.5.5
Mac Oculus Runtime for OS X v0.4.3-beta Oculus SDK for OS X v0.4.3-beta Unity v4.5.5

Oculus Riftの開発環境
Setup Tool
Oculus Platform SDK *2

Oculus の構成

Windows上でUnityを使った際の構成を画像で示します。

f:id:subrutm:20161020230956p:plain

Oculus の相関図

OVR系クラスの主要なクラスの相関図を以下の画像にまとめました。
f:id:subrutm:20161021224434p:plain

クラスのメンバ変数・メンバ関数 説明

上記、相関図のクラスのうちの主用なクラスのメンバ変数及びメンバ関数を示します。
調査環境は、Unity v5.x, Oculus Utilities for Unity 5 v1.8.0です。

■OVRManagerクラス

OVR系APIの中心的なクラスです。
このクラスを中心に周囲のクラスを管理しています。

インスタンス

R: Read
W: Write

+メンバ名称 型名 属性 役割
+instance OVRManager R OVRManagerのインスタンス
+display OVRDisplay R 有効なディスプレイへの参照
+tracker OVRTracker R 有効なセンサーへの参照
+boundary OVRBoundary R 有効な検出領域設定への参照*3
+profile OVRProfile R ユーザの設定情報や身体情報など

●イベントをトリガーにしたコールバック系

+メンバ名称 型名 属性 役割
+HMDAcquired event Action - HMDが割り当てられた
+HMDLost event Action - HMDが認識されなくなった
+HMDMounted event Action - HMDがユーザーの頭に嵌った
+HMDUnmounted event Action - HMDがユーザーの頭から離れた
+VrFocusAcquired event Action - VR焦点を得られた
+VrFocusLost event Action - VR焦点を失った
+AudioOutChanged event Action - 音出力デバイスの変更とリスタートが必要
+AudioInChanged event Action - 音入力デバイスの変更とリスタートが必要
+TrackingAcquired event Action - センサーがトラッキング対象を得た
+TrackingLost event Action - センサーがトラッキング対象を失った
+HSWDismissed event Action - 『Health & Safety Warning』というウィンドウが消えた

※『Health & Safety Warning』とは・・・

以下の画像のように表示される注意書きのウィンドウの事で、何かキーを押すことで消えます。
f:id:subrutm:20161021104216p:plain


●状態チェック・設定系

R: Read
W: Write

メンバ名称 型名 属性 初期値 役割
+isHmdPresent bool R / W - trueなら、接続されていて存在している
+audioOutId string R - 音声出力デバイス識別子*4
+audioInId string R - 音声入力デバイス識別子*5
+hasVrFocus bool R - trueなら、アプリケーションはVR Forcusを持っている
+isHSWDisplayed bool R false 常にfalse(必ず表示する)
+DismissHSWDisplay bool - - 使用されていない
chromatic bool R / W - trueなら、テクスチャーの帯域幅をコストにして色彩を改善する。
monoscopic bool R / W - trueなら、両眼は同じ絵を見る。(両眼の中心で描画する、パフォーマンスを節約し快適にする)
queueAhead bool R / W true trueなら、描画処理の映像のゆがみをCPU-GPUをパラレルで動かすことで1/4フレーム高速化する
useRecommendedMSAALevel bool R / W false trueなら、Unityがハードウェアのパフォーマンス・クォリティーに合った最適なアンチエイリアシングレベルを設定する
enableAdaptiveResolution bool R / W false trueなら、動的アクセラレーションを許容する
maxRenderScale float R / W 1.0f アプリケーションが適応可能な解像度モードの最大倍率を設定[設定可能範囲: 0.5~2.0f]*6
minRenderScale float R / W 0.7f アプリケーションが適応可能な解像度モードの最小倍率を設定[設定可能範囲: 0.5~2.0f]*7
vsyncCount int R / W - FPS(Frame per seconds)の値
+batteryLevel float R - バッテリ残量を取得
+batteryTemperature float R - バッテリの温度を取得
+batteryStatus int R - バッテリの状態を取得
+volumeLevel int R - 音量レベルを取得
+cpuLevel int R - CPU性能のレベルを取得
+cpuLevel int R / W - CPU性能のレベルを取得
+gpuLevel int R / W - GPU性能のレベルを取得
+isPowerSavingActive bool R / W - trueなら、CPU/GPUの使用電源を抑える
+trackingOriginType OVRManager.TrackingOrigin R / W - ラッキング対象の種別(EYE LEVEL, FLOOR LEVEL)
usePositionTracking bool R / W true trueなら、位置トラッキング機能をOVRCameraRigのカメラと同期する
useIPDInPositionTracking bool R / W true trueなら、ユーザーの目と目の距離をOVRCameraRigのカメラと同期する
resetTrackerOnLoad bool R / W false trueなら、各シーンをロードする度に頭の位置をリセットします。(原点とベクトルを再設定する)
isSupportedPlatform bool R - trueなら、VRがPlatformに対応している
isUserPresent bool R - trueなら、ユーザーがHMDを着用している

●外部から参照できる関数

メンバ関数名称 戻り値 引数 役割
ReturnToLauncher - - 関数をコールするとアプリやゲームから離れて、ランチャーメニュー/ダッシュボードに戻る
+PlatformUIConfirmQuit - - 関数をコールすると終了選択画面が表示される
+PlatformUIGlobalMenu - - 関数をコールするとグローバルメニュー画面が表示される

まとめ

Deviceまわりの設定は、OVRManagerである程度機能する事が見えてきたと思います。
各メンバ変数のアクセス方法は、以下の通りとなります。

	void test() {
		// staticなメンバの場合は、以下の書き方でアクセス可能です。
		if( OVRManager.isHmdPresent ) {
			// HMDが有効で使える状態でする処理を書く
		}

		// 通常のpublicメンバの場合は、以下の書き方でアクセス可能です。
		OVRManager.instance.usePositionTracking = false;
	}

*1:DK2向けのSDKは、C++によるライブラリやAPIサンプルコードが入ってました。

*2:2016/10/20現在 最新バージョン。

*3:センサーが検知する空間の境界, VIVEとかが参考に成るかもしれない

*4:Windows audio endpointが使用するためのIMMDevice(Multi Media Device Interface)のUUID(Unique User ID)を得る

*5:Windows audio endpointが使用するためのIMMDevice(Multi Media Device Interface)のUUID(Unique User ID)を得る

*6:enableAdaptiveResolutionが有効になっていることが前提

*7:enableAdaptiveResolutionが有効になっていることが前提

VRの歴史

VRの起源

最近、VRが話題沸騰してますが、起源はいつからかご存知でしょうか?
実は、1989年にバーチャルリアリティという言葉が誕生しました。
なので、専門家の『VR元年』とは、1989年なのです。


没入感を得られるVRシステムとして、1992年にCAVEという方式のVRシステムが発表されました。

Cave automatic virtual environment - Wikipedia

イリノイ大学シカゴ校で開発された仕組みで、HMD形式では視野角に限界がある事から箱形のディスプレイの中に人が入ることで、その課題をクリア出来ないかと考え試作されたそうです。

メガネにセンサーを付けることで位置をトラッキングして、ボックス型の部屋に人の方向に合わせた映像を投影するシステムでした。

これは、大変大掛かりで場所もとる仕組みだったようです。

イメージとしては、以下の通りとなるようです。

Visbox, Inc. | CAVE Systems

www.youtube.com


現在、主流となっているHMDはどこから来たのか?

現在、主流となっているHMD(Head Mount Display) がどこから来たのかと言うと、始まりはARと言う形で1938年に登場しています。
単なる、頭に着けるディスプレイと言う意味では、始まりは1938年です。

詳細は、たくさん説明ページがあるので省きます。 (最後にオススメのページを紹介します。)

CAVEが開発されていた時代には、HMD型のVRの研究開発が盛んだったそうです。 (日本バーチャルリアリティ学会の資料より)
そう考えると、Oculusの登場までにエラく時間が掛かったんだなと思いました。。

現在主流となっている、VR機器とはARとして開発されたHMDとCAVEで培われたトラッキング技術を融合させた技術と言えます。

私は、さらに先のHR(Holographic Reality)を目指したいと思ってます!

前身技術やARを含めた詳細な歴史は、以下のページが参考になりそうです。

www.vrs.org.uk

www.moguravr.com

VRの利用制限

VRには、利用制限があることをご存知でしょうか?

例として、以下の記事があります。

netgeek.biz

今回は、3Dの仕組みと視野角の関係について単調に説明します。
VRとは、片目毎にレンズが装着されており、視野角が80°~120°の範囲で対応しているようです。


※現在注目されているVR機器は、以下の通りです。

www.dronediy.jp

ちなみに、人間の視野角は、100°~110°です。
擬似3D空間は、独自の世界空間を持っていることから擬似空間に合った位置から鑑賞しないと意図した映像を見ることが出来ないのが現状です。


スクリーンから離れすぎていてもNGですし、近すぎてもNGなのです。

3Dとは、以下のようにスクリーン上に遠近法を利用して遠近感を擬似的に創ることで2D平面に立体を表現する手法です。
f:id:subrutm:20161019145526p:plain

 

人間の目から考えると以下の画像の通りになります。

f:id:subrutm:20161019150231p:plain

※カメラ: 擬似空間のカメラ
※視錘台の手前側平面は、スクリーン・画面

最初に掲載したVRの問題点の記事では、3D映画となってますが、3D映画はスクリーンが固定で、座る座席によって目の位置が変わります。
なので、スクリーンに近く](または遠く)なるほど、立体視とは程遠い映像が見えることになることは理解できると思います。

VRは、特に「スクリーンと目の距離」が近くなります。
一人称視点で動かせるシステムを作ると、各々にカメラを着ける事によって、より一層リアルな没入感が得られます。

f:id:subrutm:20161019154641p:plain

コンテンツの視錘台の設定によっては、生物的な視野角と合わなくなる可能性があるため注意が必要です。
レンズの位置を目の幅に合わせることは出来るが、奥行きを調整する機能は無かったので、遊びすぎたりするのも健康に悪いので留意しましょう。

 

【VR】挑戦の日々がスタートする

Oculus DK2とhTc Viveを借りてVRの開発の感触を試してみた。

Viveの方は、センサー2つとコントローラーが2つ、HMD(Head Mount display)がついてます。
自宅が狭すぎて、センサーを設置できずViveは試すことが出来ませんでした。

(今週末に試す予定です。)

Oculus DK2 (Development Kit Ver.2)のほうは、トラッキングセンサーがひとつとHMDがあるだけでした。
最新のセットアップツールでは、動作しなかったので、0.4.3-Betaの環境でサンプルアプリの動作を確認した。
とても、違和感の無い世界が広がっていて、今回は本格的に没入感が強く得られるなという印象が強かったです。

貸主のところでもデモを見せるつもりで、準備したのですがDisplay周りが断線したのか動作しなくなってしまいました。

使える機材が無くなったけど、地道にUnityだけでアプリ開発の勉強をしています。
父ちゃん、孤軍奮闘だぁ・・・・w (FFXⅢ サッズのセリフ)
※Oculus DK2は、beta版しか動かないので最新の機能を試すことは出来ないことがわかった。 (DK2向けのAPIは、C++言語が

 

 

ベースでした。)
正式版は、Unity用のAPIが用意されており、C#などのスクリプトで開発が可能です。