Unity
WORLDEYE

[Unity]ワールドアイに3D空間を描画する

ニューワールドアイ

を買ってみました。ニューが出てるのでそちらを。これ、HDMIで出力できるとなれば、なんでもできますね。なかなか面白いデバイスなので、自由に描画することを目指します。ちなみに値段が変動しているようですが、僕が購入した先週は8,400円でした。

特性評価

まずはデバイスの特性を把握します。チェック模様を描画させてみましょう。さらに白線で真円を書いておきます。PCからHDMIで接続しておけば、セカンドディスプレイとして表示できました。
IMG_2768.png

平面を出すとこうなります。頑張って空間に対応しましょう。

正距方位図法(Azimuthal Equidistant Projection)

あれこれ観察した結果、マッピングは正距離方位図法を使うのがよさそうです。

Wolframさまより:
http://mathworld.wolfram.com/AzimuthalEquidistantProjection.html

x=k'cos\phi sin(\lambda-\lambda_0) \\
y=k'{cos\phi_1 sin\phi - sin\phi_1 cos\phi cos(\lambda - \lambda_0) } \\
k'=\frac{c}{sin c} \\
cos c = sin\phi_1 sin\phi + cos \phi_1 cos \phi cos(\lambda-\lambda_0)

素晴らしい。こんな式、自力で導出できる気がしません。

キューブマップを作る

まずは全方向に対応するとして、6方向でカメラを6つ用意してレンダリングします。結果はキューブマップそっくりになりますね。そして、各面に矩形のメッシュを想定し、それぞれの頂点を緯度経度に変換してから正距離方位図法の式に入れてメッシュを作ります。

ただし背面については特異点があるので、穴を開けておきます。背面の変換前。よく見ると中央に穴が空いているのがわかるでしょうか:

スクリーンショット 2017-09-06 23.00.31.png

6面の変換後:

スクリーンショット 2017-09-06 22.58.42.png

実際の変換のレンダリングはキューブマップではないです。もっともシンプルなシェーダで済みます。

そしてワールドアイの特性上、背面は必要ないので、6面でなく5面だけレンダリングします。(6面は単にやってみたかっただけ)

スクリーンショット 2017-09-06 23.07.52.png

こうなります。なお、ワールドアイの描画範囲が完全なる半球だとすると、参照するのは上下左右の4つの面の半分しか使いません。背面だけを除くのではまだ余計にBlitしていることになります、が、どうせカメラは5つぶん描画するのだし、転送のシェーダも軽いことだし、たいした無駄ではないでしょう。将来ワールドアイの表示領域が270度まで広がるかもしれないしね!

完成

worldeye.gif

YouTube:
https://www.youtube.com/watch?v=2Vrm3TNCzUc
https://www.youtube.com/watch?v=2lHPjGVEFHo

ソースコード含むプロジェクト

はこちら:
https://github.com/dsedb/WorldEyeProjection

使ってもらうにしてはあんまり丁寧な作りではないですが、シンプルなプロジェクトなのでシーンにある物体やらを取り除けば好きに使えると思います。

注意

環境によって、アスペクトが狂うときがあるようです。4:3になっているかなっていないか、みたいな差が出る模様。
AzimuthalEquidistantProjection.cs
をAddしたオブジェクトをインスペクタで見たときの
`Consider Aspect'
をオンオフすることで調整してみてください。Windowsだとチェックを入れて、Macだとチェックを入れない、で合うようだ、というのが目下の観察結果です。
スクリーンショット 2017-09-06 23.15.11.png