Oculusインストール環境のトラブルと対策
OculusのインストールでのPCIドライバインストールエラー
私のノートPCでドライバのインストール中にPCIドライバだけがエラーを出していた。
Specは、以下の通りである。
CPU: Xeon E3-1505M
GPU: nVidia Quadro M1000M
とある店舗の店員から聞いた話ですと、Optimus機能があるとOculusのドライバがインストールされないという情報を得たので検証してみた。
※実機があっての比較ではなく、機能差分等での比較となります。
Optimus機能とは何か?
GPUの負荷具合を基に判断して、Intel GPUとnVidia GPUを切り替える機能。
ラップトップ(ノートPC)の消費電力を抑える目的で作られた機能です。
NVIDIA Optimus Technology: Performance and Battery Life for your Notebook | How Optimus Works
Optimus機能をOFFにする方法はあるのか?
以下の2つの記事を発見した。
内容を見ると、BIOSの設定とドライバーをインストールする際にカスタムインストールを選択する事で関連ドライバのインストールを回避できるとある。
Devel/OculusRift/製品版のセットアップ - cubic9.com
が、私のPCのBIOSではこれらの設定を弄る項目が無く対応していなかった。
LINUX系ならなんとかなりそうだが、Windows専用なので意味が無い。
別の観点で調べてみた
上記の通り、設定を変えるという観点では失敗に終わった。
なので、External GPUという方法でラップトップPCを拡張する形でVideoボードを出すことを検討してみました。
調査した結果、3つほど救済策があることが分かった。
1. Dell ALIENWARE グラフィックボード外部拡張外付けボックス
Amazon CAPTCHA
この機種はビデオボードの外付け及び拡張には向いてますが、出力端子がDellの
ALIENWAREシリーズ専用になっていて、他では使えない制約があります。
私のワークステーションは、Dell製ですがALIENWAREシリーズではないので接続できません。
なので、選択肢としてはなくなりました。
2. Mac向けの外部接続 PCI-E Box
MacでPCI-Eを使って拡張したい人向けの救済策として用意されている商品になります。
公式を見るとWindowsでもThunderboltさえ対応していれば使えるようでした。
しかし、PCI-Eに挿して使えるボードとしては、HDDやサウンドボード、ビデオキャプチャーボード、ネットワークボードなどでした。
ビデオボードを挿してもnVidiaのドライバにブリッジする必要があり、ソフト的な対応が必要になるためNGでした。
【正規国内品】ソネット SONNET Echo Express SE I Thunderbolt 2-to-PCIe Card Expansion Chassis
HighPoint RocketStor 6361A デュアルThunderbolt接続 拡張アダプタ PCI-Expressポート
3. PCI-Eボード
PCI-Eのみを剥き出しにしたPCI-Eボードという選択があります。
以下の2つはPCI-Eですが、ver 2.0止まりで最新のビデオカードが挿ささらないと分かった。
出力端子もExpressカードで昔のスタイルでした。
DIR-EB262-シリーズ - PCケース&パーツ、オーディオのパイオニア-株式会社ディラック
また、海外でのE-GPUの動画を発見しました。
これを参考にして、外付けGPU用のPCI-Eボードを発見しました。(日本でも輸入可能です。)
端子が、mini PCI-EになっていてラップトップPCのボードで切り替えが出来れば使える事が分かった。
ビデオボードを拡張できてBIOS次第では切り替えも可能な方法はこれしかないと分かりました。
そこで、私のPCの構成を調べてみた結果ですが、私のQuadroはマザーボード上にチップが載っていてPCI-E自体を使用していない事が分かりました。
よって、私のラップトップから拡張してGPUを活用する方法が絶たれてしまったという結果に終わりました。
結論:
Oculusを使うためにNoteを買うときは、PCI-Eに注意するかOculusが推奨するGPUが載っているPCを購入するかのいずれかを選択するほうが無難です。
360°パノラマビューをUnityで作ってみた
今流行の360°ビューの仕組みとは
細かく書くと難しくなるので、簡単に書いていきます。
360°撮影できる機材を使ってパノラマ撮影した画像・映像を
擬似空間の球体(正距円筒球)の内側に張り付けて球体の中心に
カメラを設置してユーザーに見せる事であたかも自分の周りに
撮影した景色があるかのように見える技術の一つです。
ポイントは、正距円筒球を使う事です。
正距円筒球とは何か?
擬似空間でのポリゴンの表現がどんな形状で出来ているかご存知でしょうか?
実は、3D空間ではすべて3角形で表現します。
美術でも遠近法が用いられることにより奥行きを感じるのと同じように
カメラから離れた位置にある三角形メッシュほど、縦長に大きくなることが
分かると思います。
画像を張り付ける手法は、頂点情報に画像の座標を記録し、それを
三角形メッシュで描画しているので画像を加工しないでそのまま
描画すると不自然な形になるのはイメージ出来ますでしょうか?
違和感の無い画像表現をする為には、球の頂点位置と画像座標が適切に
マッチさせてあげる必要があると理解できると思います。
ここからは、テクスチャーマッピングの話です。
下記のように、平面(ABCD)と画像(abcd)があるとします。
法線は、あなたに向かってくる方向が法線ベクトルの方向とします。
- ABCD = abcdの場合
元画像の解像度と等倍で正常に表示される。
- ABCD > abcdの場合
元画像の解像度より拡大して表示される。
- ABCD < abcdの場合
元画像の解像度より縮小して表示される。
この例から分かるように、3D空間のメッシュの大きさと画像の大きさが
マッチしないと倍率に差が出てしまい、表示が不自然になってしまう。
だから、球面の三角形に合わせた画像を作る必要があり、その手法が
正距円筒図法と呼ばれます。
これを応用すると、パノラマ投影法[プロジェクションマッピング]
になる訳です。
詳細な変形手法としては、詳しいサイトがありますのでそちらを参照下さい。
空雲礼賛
正距円筒球を入手する方法は?
正距円筒球の入手手段は、インターネットでダウンロードか
機材を用いて撮影するかの二択になります。
Unityで360°パノラマビューを作ってみる
上記の何れかの方法で入手した画像素材を利用して、360°ビューを表示してみましょう。
手順1. カスタムシェーダーを作成する
①カスタムシェーダーファイルを新規作成する
②以下のコードに書き換える。
Shader "Custom/InwardShader" { Properties { _MainTex ("Albedo (RGB)", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 Cull Front CGPROGRAM // Physically based Standard lighting model, and enable shadows on all light types #pragma surface surf Standard vertex:vert//fullforwardshadows // 法線ベクトルを内側に向ける設定 void vert(inout appdata_full v) { v.normal.xyz = v.normal * -1; } sampler2D _MainTex; struct Input { float2 uv_MainTex; }; void surf (Input IN, inout SurfaceOutputStandard o) { // Albedo comes from a texture tinted by color fixed4 c = tex2D(_MainTex, IN.uv_MainTex);// * _Color; o.Albedo = c.rgb; } ENDCG } FallBack "Diffuse" }
手順2. Materialの設定を利用する
①: 影は無用なのでチェックを外す
②: マテリアルのシェーダー設定を作成したシェーダーに変更する
手順3. MainCameraの位置を球体の中心に設定する
手順4. 環境光を消して、スポットライトで内部を照らす
①環境光を消す
②スポットライトを新規作成する
③必要ならパラメータを修正する
手順5. 球体を回転させるスクリプトを作成
using UnityEngine; using System.Collections; public class Rotator : MonoBehaviour { public Vector3 rotateRate; // Use this for initialization void Start () { } // Update is called once per frame void Update () { transform.Rotate(rotateRate * Time.deltaTime); } }
作成したスクリプトを球体にアタッチして再生すると、360°パノラマビューの
簡単なテストアプリの完成です。
VR美術館の試作にて光源の描画問題ではまった件
VR向けの美術館とは
現在、VR向けの美術館として照明と絵画で演出を工夫しながら考えています。
以下の写真は、開発中のスクリーンショットになります。
照明としては、2タイプを使っていました。
タイプ1. 全体的に照らす天井の照明
タイプ2. 絵画を照らすための照明
問題点は、ある条件のときにタイプ2の照明が描画されない問題が発生した。
※表示は、スクリプトで作成しているので、照明の条件はすべて同じです。
解決するには、優先順位を高くしろ!
Lightの設定にある【Render Mode】を【Important】にすると改善します。
Lightの構成が、写真の通りだとする。
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軸回転させているだけです。
敵から迎撃を受けてます。
ダメージ受けているのですが、危険レベルまで減ってしまって赤くなっているところです。 (中間色として、黄色もあります。)
プレイヤーが攻撃しているところです。
・これから企画として創ろうとしている作品
VR美術館
VRを使った、絵画鑑賞の空間を作ります。
スポットライトを使った雰囲気の演出などを工夫して、絵画を飾り一人称カメラで実際に擬似空間を散策しながら参照する流れです。
部屋のようなダンジョンにも応用できるので、部屋のような空間での当たり判定や演出効果の学習を兼ねたプロジェクトです。
外観です。
内装です。
VRスーパーマリオブロス
学生時代でもやっていたマリオの模擬作品です。
VRを使ってマリオになりきろう!という想いから発足したプロジェクトです。
下準備としてブロックを設置してみただけの画像ですが、今後拡張していきますので開発途中のノウハウなどを公開するのでお楽しみに。
完成したら、遊んでみましょうw
最後まで、読んで頂きありがとうございました。
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 の相関図
OVR系クラスの主要なクラスの相関図を以下の画像にまとめました。
クラスのメンバ変数・メンバ関数 説明
上記、相関図のクラスのうちの主用なクラスのメンバ変数及びメンバ関数を示します。
調査環境は、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』とは・・・
以下の画像のように表示される注意書きのウィンドウの事で、何かキーを押すことで消えます。
●状態チェック・設定系
R: Read
W: Write
メンバ名称 | 型名 | 属性 | 初期値 | 役割 |
---|---|---|---|---|
+isHmdPresent | bool | R / W | - | trueなら、接続されていて存在している |
+audioOutId | string | R | - | 音声出力デバイス識別子*4 |
+audioInId | string | R | - | 音声入力デバイス識別子*5 |
+hasVrFocus | bool | R | - | trueなら、アプリケーションはVR Forcusを持っている |
bool | R | false | 常にfalse(必ず表示する) | |
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形式では視野角に限界がある事から箱形のディスプレイの中に人が入ることで、その課題をクリア出来ないかと考え試作されたそうです。
メガネにセンサーを付けることで位置をトラッキングして、ボックス型の部屋に人の方向に合わせた映像を投影するシステムでした。
これは、大変大掛かりで場所もとる仕組みだったようです。
イメージとしては、以下の通りとなるようです。
現在、主流となっているHMDはどこから来たのか?
現在、主流となっているHMD(Head Mount Display) がどこから来たのかと言うと、始まりはARと言う形で1938年に登場しています。
単なる、頭に着けるディスプレイと言う意味では、始まりは1938年です。
詳細は、たくさん説明ページがあるので省きます。 (最後にオススメのページを紹介します。)
CAVEが開発されていた時代には、HMD型のVRの研究開発が盛んだったそうです。 (日本バーチャルリアリティ学会の資料より)
そう考えると、Oculusの登場までにエラく時間が掛かったんだなと思いました。。
現在主流となっている、VR機器とはARとして開発されたHMDとCAVEで培われたトラッキング技術を融合させた技術と言えます。
私は、さらに先のHR(Holographic Reality)を目指したいと思ってます!
前身技術やARを含めた詳細な歴史は、以下のページが参考になりそうです。