前回の記事「アーマードコア6のパノラマ画像を合成してVR作業環境の背景にする」の続き。
今度は、立体視できるパノラマ画像を作ることに成功した。見回せるだけでなく、遠近感がついた。VRヘッドセットで鑑賞すると、目の前に機体があり、手を伸ばせば触れることができそうだ。臨場感と立体感に脳を焼かれる。これはぜひ体験してもらいたいので、作り方を解説する。ちょっと手間はかかるが、その価値はある。
どんな出来上がりになるのかをお伝えするため、サンプルを置いておく。VRヘッドセットをお持ちの方はリンク先の画像をダウンロードして試してみてほしい。Meta Questユーザの方は、「Meta Questヘッドセットで開く」のリンクをクリックすると簡単にURLを送れる。
- 3Dパノラマ ライガーテイル
→ Meta Questヘッドセットで開く - 3Dパノラマ スティールヘイズ
→ Meta Questヘッドセットで開く - 3Dパノラマ デュアルネイチャー
→ Meta Questヘッドセットで開く
(追記) 今回の記事のようにパノラマを作るのはけっこう難しいのだが、視差をつけた撮った2枚の画像を立体視するだけでもかなり面白い。詳しくは新たな記事「2枚の平面画像をパノラマ化してMeta Questで立体視 (その1 概要編)」に書いた。Lightroomも使わずにBlenderかPythonのプログラムで作れて、失敗も少ない。
概要
パノラマ立体視画像を作る手順はこんな具合だ。

- AC6のフォトモードでスクリーンショットを撮る
- Adobe LightroomのPanorama Merge、あるいは同等の機能を持つ別のソフトウェアを使って2セットのパノラマを生成する
- ステレオ化
- 鑑賞する
今回の記事では、Meta Quest 3の標準のビューア用のフォーマットで鑑賞できる画像を生成した。Equirectangular (正距円筒) 図法のパノラマ画像を2枚上下に並べるというシンプルなフォーマットだ。
立体視の仕組み
パノラマ化については前回の記事で解説したので今回は詳細には触れない。立体視の仕組みをちょっと説明しよう。

人類は、左右に並んだ2つの目を持ち、異なる位置からの入力を脳で処理することで立体感を把握している。左目と右目のように少し離れた場所から撮影した映像、あるいは見え方をシミュレートした映像を用意し、それぞれを左目と右目で見ることで立体視が実現できる。
実際作るには
実際に全方位立体視を実現しようとするのはちょっと大変だ。VR環境でリアルタイムで動くCGの場合は、頭の向きに合わせて左目用と右目用の映像を生成する。しかし、静止画の場合、どちらを向いても破綻のない画像を生成するのはちょっと難しい。人間がその場でぐるりと周囲を見渡す場合、目も移動する。その目の移動を反映するように撮影し、シームレスにつながなければならない。

ゲーム内でそれをやるのはかなり困難なので、「後ろは見ない」と割り切って作ることにした。椅子に座って鑑賞するぶんにはそれで十分だ。「正面」を向いたときに破綻なく鑑賞できるよう、「左目のポジション」「右目のポジション」を固定してして撮影する。

実際の手順
撮影準備
撮影準備については、前回記事の「スクリーンショットを撮ろう > OS設定を変更」の箇所を参照し、スクリーンショットを撮りやすい状態にしておくこと良い。
JPEGはやめておけ…
スクリーンショットの保存形式がJPEGになっている場合、PNGに変更しておくことを強くおすすめする。
立体視しなければJPEGで保存した画像をパノラマ化しただけでもけっこう良い物ができたりするのだが、立体視するとJPEGの圧縮アーティファクトが目立ってしまい、モヤがかかったような見え方をする。
画面に目印をつける
撮影前に画面の真ん中に印をつけることをおすすめする。付箋でもいいし、マスキングテープなどでもいい。この印があるのとないので成功率が大違いになる。

位置合わせも正確になるし、カメラをどれくらい動かしたのかがわかりやすい。また、撮影を始めるときには、画像の「中心」として記憶しておくと、2セット目のパノラマを撮るときに撮影条件を再現しやすい。
撮影
撮影については「スクリーンショットを撮ろう > ゲーム内で撮影する」に詳しく解説してある。
まず位置を決めて撮影する。カメラを水平にし、水平線上のどこかを「中心」と決め、画面の中央をあわせる。たとえば機体の頭部など、わかりやすい箇所が良い。どこを「中心」にするかは、後で位置合わせをするときに重要になってくる。

こんな感じで1セット撮影したら、また画面中央を「中心」に合わせる。
そしてほんの少し撮影地点をずらし、もう片方の「目」のポジションから撮影をする。ずれるのはほんの少し、スティックを最も軽く1回傾けるくらいの気持ちでいい。ほんの少しずれればリアルなスケール感が味わえる。もう少し大きくずらすと、ミニチュアを接写したような立体感になる。あまり動きすぎると、遠近感が強すぎたり立体視が破綻したりする。撮影地点が決まったら、もう1セット、なるべく同じ条件で撮影をする。
ここの細かい操作がやりにくい場合は、「カメラ速度」の設定を少し小さな値にすると良い。

パノラマ合成
撮影したスクリーンショットをUSBメモリなどを使ってPCに取り込み、Adobe LightroomのPhoto Merge機能、もしくは同様の機能を持つソフトウェアでパノラマ画像を合成する。

Adobe Lightroomならば、画像を選択して “Photo > Photo Merge > Panorama Merge” を選び、”Projection” の項目は ”Spherical” を選ぶ。
詳しくは前回の記事の “パノラマを合成する” で解説している。
パノラマ画像ができたらエクスポートする。2セットともうまく合成できればステレオ化は目前だし、1枚しかできなくても普通の全周囲パノラマ画像として楽しめるので捨てずにとっておこう。
エクスポートの形式はTIFFかDNG形式がいい。
JPEGはやめておけ…
仕上げ
左目画像と右目画像の2枚が無事に合成できたら、いよいよ仕上げだ。ちょっと泥臭い手作業になる。
PhotoshopやGIMPなど、レイヤーを扱える画像処理アプリケーションがあると良い。
DNG形式のファイルをPhotoshopで開くと自動で色調が調整されるが、左目と右目の画像の色調が違うと良くない。同じ調整を施して開く必要がある。すべてゼロにするか、プリセットを作ってしまうのがおすすめ。

位置合わせとサイズ調整
そのまま画像を上下に配置しただけだと、中心の位置がずれているので、揃える必要がある。手動で丁寧に編集してもいいが、作り方がだいぶ安定したので自動化スクリプト (Photoshop限定) も用意してみた。
手動の場合
右目画像と左目画像をレイヤーとして重ね、周囲に少しマージンを持たせて作業する。表示非表示を切り替えたり、透明度を変えたりして、比較しやすいようにすると良い。
最初にとりあえず左目画像と右目画像を取り込んだところ。上のレイヤーを半透明にしてあるが、位置がずれている。

撮影時に「中心」として選んだ箇所が右目画像と左目画像でだいたい同じ位置にくるように調整する。特に垂直方向の位置はできる限り厳密に合わせる。

こちらの例では頭部を基準にして撮影したので、重ねたときに頭部のズレが最小限になる位置に動かした。
左右の端が合わない場合は、移動させて揃える。元々の画像が円筒を適当な場所で切り開いて長方形にしたものなので、左右の端はつながっている。

左右の端が揃ったら左右をトリミング。

上下の端に透明の部分が残っている場合や、うまく合成できずに穴があいてしまった部分があれば、適当な色で塗りつぶす。近傍の色をスポイトで拾って塗ると違和感が少なくて済む。

左目画像と右目画像が同じサイズになったら、必要に応じて上下を調整する。パノラマ合成によって完全に全方位のequirectangular画像ができた場合は、縦横比が1:2になる。これよりも縦が細い場合、真上もしくは真下が切れてしまっている。本来の高さの8割を下回っている場合は鑑賞時に歪みが目立つので、キャンバスサイズを「横幅の半分」にし、撮影時の「中心」が垂直方向の中央になるように調整し、余白は適当に塗りつぶす。
スクリプトを使う場合
Photoshop限定だが、スクリプトを用意した。こちらのコードをコピーし、 “panorama_placement.jsx” などといったファイル名で保存しておく。拡張子は “jsx” にする必要がある。
#target photoshop
var dialog = new Window("dialog", "Center coordinate");
dialog.orientation = "column";
dialog.add("statictext", undefined, "X:");
var centerX = dialog.add("edittext", undefined, "1000");
dialog.add("statictext", undefined, "Y:");
var centerY = dialog.add("edittext", undefined, "500");
var okButton = dialog.add("button", undefined, "OK", {name: "ok"});
okButton.onClick = function() { dialog.close(); };
dialog.show();
var centerX = parseInt(centerX.text);
var centerY = parseInt(centerY.text);
var doc = app.activeDocument;
var layer = doc.activeLayer;
layer.name = "main";
var origWidth = doc.width.as("px");
var origHeight = doc.height.as("px");
var newHeight = origWidth / 2;
var offsetX = centerX - Math.floor(origWidth / 2);
var offsetY = centerY - Math.floor(newHeight / 2);
if (offsetX < 0) {
duplicateAndMoveSelection(doc, origWidth + offsetX, 0, 0, 0, -offsetX, origHeight);
} else if (offsetX > 0) {
duplicateAndMoveSelection(doc, 0, 0, origWidth-offsetX, 0, offsetX, origHeight);
}
layer.translate(-offsetX, 0);
doc.mergeVisibleLayers();
if (newHeight > origHeight) {
doc.resizeCanvas(origWidth, newHeight, AnchorPosition.TOPCENTER);
}
layer = doc.activeLayer;
layer.translate(0, -offsetY);
var bgLayer = doc.artLayers.add();
bgLayer.move(layer, ElementPlacement.PLACEAFTER);
doc.selection.selectAll();
doc.selection.fill(app.foregroundColor);
doc.selection.deselect();
doc.mergeVisibleLayers();
function duplicateAndMoveSelection(doc, fromX, fromY, toX, toY, width, height) {
var selRegion = [[fromX, fromY], [fromX + width, fromY], [fromX + width, fromY + height], [fromX, fromY + height]];
doc.selection.select(selRegion);
doc.selection.copy();
var newLayer = doc.artLayers.add();
doc.paste();
newLayer.translate(toX - fromX, toY - fromY);
doc.selection.deselect();
}
こちらは処理前の画像の例。パノラマ合成には成功したが、中心に据えたい機体が左に寄り、上下も切れてしまった (真上・真下部分の画像が足らなかった、あるいはうまく合成できなかった場合はこうなる) ので、大幅な調整が必要だ。

まず、撮影時に「中心」と決めた箇所の座標をチェックする。”Info” ウィンドウを出した状態でカーソルを合わせるとX・Yが表示されるので、これをおぼえておく。こちらの例では、「腰の部分の銀色のパーツの右上の角」に合わせている。

“File > Scripts > Browse…” で “panorama_placement.jsx” を選択してスクリプトを呼び出す。ダイアログが出るので、さっきチェック「中心にしたい箇所」のX・Y座標を入れる。

あとはスクリプトがうまいことやってくれて、水平方向の中心が揃い、上下の足らない部分は塗り足される。

グリッドと比較してみるとぴったりである。

同じ処理をもうひとつの画像に対しても行うと、左目・右目画像の位置揃えが完了する。
なお、上下の足らないところを塗り足した場合、実際に鑑賞するとこんな感じに黒い穴になる。よほど真上を見上げない限り気にならないだろう。

両目画像を配置
これで位置調整は終わり。キャンバスサイズを縦方向に2倍する。

Photoshopは数値を入力する欄に簡単な数式を入れると計算してくれるのでちょっと便利。

これで正方形のキャンバスができたら、上に左目用、下に右目用の画像を配置する。

これを画像として書き出せばできあがり。PNG形式がおすすめ。
JPEGはやめておけ…
VRで鑑賞する
できた画像をVR環境に読み込んで鑑賞する。
詳細は前回記事の「鑑賞 > VRで」の箇所で解説した。Meta Quest 3の環境では、OS標準の “Browser” を使って画像をダウンロードするという方法を使った。
鑑賞の際は、”360 3D” を選ぶ。

被写体とロケーション選びのtips
今回はガレージにプリセット機体を置いて撮る例をお見せしたが、フォトモードに突入できる場所ならミッション中でもいい。




ただし、成功しやすい被写体、難しい被写体などいろいろあるようだ。
- 脚にボリュームのある機体はPhoto Mergeが成功しやすい。とくに四脚や大きめのタンク。真下を見たときに映る脚が合成時の位置合わせの目印になるのかもしれない。
- 二脚をガレージ内で撮影する場合はあまり高い位置から撮るとうまくいかないことが多い。腰くらいの高さから見上げるほうが合成がうまくいきやすい。
- つるつるすべすべした機体のほうが出来上がりが自然になるので初心者向け。ウェザリングの入った機体 (無印スティールヘイズやナイトフォール) や細かい凹凸の多い機体 (BASHOフレーム等) は、立体視したときに左右の画像の細かい差異が目立ち、不自然なノイズが発生する。
- ミッション中の風景の場合、変化の少ない地面や空の面積が大きかったり、遠景に似た形のオブジェクトが並んでいたりすると失敗しやすい。建物に囲まれた場所や屋内、大量のミサイルの飛び交うバトルシーンなどがおすすめ。
- 空がのっぺりしている場合、自分でミサイルをばら撒いて少し派手にしておいてもいい。
- どうしても床がのっぺりしていたり遠景に変化が少なかったりする場合、背後の地面にパルスシールド投射器EULE/60Dでパルス球を設置すると目印になってパノラマ合成がうまくいったりする。この武器、ちゃんと使いこなせたためしが無いのだが、意外な使い道があった。ありがとうシュナイダー。
好きなシーン、好きな景色、好きな機体で試行錯誤してAC6の世界に没入してみてほしい。