Appearance
iPad Unity アプリ仕様
概要
iPad から操作し、クラウド API で2D動画を深度推定し、Looking Glass ディスプレイで立体表示する Unity アプリの設計仕様書です。MacBook 上の Cursor AI(開発担当AI)向けの引き継ぎ資料を統合・再構成しています。
開発環境
| 項目 | 値 |
|---|---|
| Unity | 6000.0.39 以上(6000.1.x も可) |
| レンダーパイプライン | URP v17.0.4 以上 |
| LKG Plugin | 4.0-alpha(Unity 6 + URP専用) |
| ターゲット | iPad + Looking Glass Portrait(USB-C接続) |
| Xcode | iOS/iPadOS ビルド用 |
LKG Plugin 4.0-alpha インストール手順
- ZIP を展開すると以下が含まれます:
com.unity.render-pipelines.core/com.unity.render-pipelines.universal/jp.keijiro.klak.syphon//jp.keijiro.klak.spout/Looking Glass Unity Plugin 4.0.1-alpha.unitypackage
- プロジェクトを閉じてから、4つのフォルダを
YourProject/Packages/にコピー - プロジェクトを開き、
Assets > Import Package > Custom Packageで.unitypackageをインポート Looking Glass Plugin/Settings/Project Setup→ Inspector のボタンを順に押して設定Looking Glass Plugin/Scenes/Multiview Example Sceneで動作確認
AI補完
重要: Looking Glass Plugin 4.0-alpha はカスタムビルドされた URP パッケージを含んでいます。通常のURPでは動作しません。プラグイン付属の com.unity.render-pipelines.core と com.unity.render-pipelines.universal を Packages/ に配置する必要があります。これにより、マルチビューレンダリングのために STEREO_INSTANCING_ON やインスタンシングが有効になります。
アプリ全体構成
シーン構成
Assets/
├── Scenes/
│ └── Main.unity ← メインシーン(1つで完結)
├── Scripts/
│ ├── Core/
│ │ ├── AppManager.cs ← アプリ全体の状態管理
│ │ ├── VideoLoader.cs ← 動画ファイル読み込み
│ │ ├── ApiClient.cs ← Modal Cloud API通信
│ │ └── RgbdSbsPlayer.cs ← RGBD SBS動画の再生制御
│ ├── Rendering/
│ │ ├── RgbdRenderer.cs ← RGBD→多視点変換 + LKG出力
│ │ ├── FocusAutoTracker.cs ← フォーカス自動追従
│ │ └── BackgroundFill.cs ← 背景色自動補完
│ ├── Export/
│ │ ├── QuiltExporter.cs ← Quilt MP4エクスポート
│ │ └── AudioMuxer.cs ← 音声合成
│ └── UI/
│ ├── MainUI.cs ← メインUIコントローラー
│ └── ProgressOverlay.cs ← 進捗表示
├── Shaders/
│ ├── RgbdParallax.shader ← メインRGBD視差シェーダー
│ └── BackgroundExtend.shader ← 背景補完シェーダー
└── Materials/
└── RgbdDisplay.matUXフロー
起動 → [HOME画面]
├── 「ローカルSBS動画を開く」→ Files picker → [再生・表示画面]
├── 「動画を変換(クラウド)」→ Files picker → [API変換画面]
└── 「最近のファイル」リスト
[API変換画面] → モデルサイズ/FPS設定 → 「変換開始」
→ プログレス表示 → 完了 → [再生・表示画面]
[再生・表示画面](メイン画面)
├── Looking Glassにリアルタイム表示
├── 再生/一時停止/シーク/ループ
├── パラメータ調整(Focus/Depthiness/FOV/Zoom等)
└── 「エクスポート」→ Quilt MP4保存RGBD→立体変換の2つの方式
方式A: 視差シェーダー(UV シフト) — AM3D iPad版の主要方式
深度に基づいてUV座標を水平方向にシフトする手法です。メッシュ変位より高速で品質が安定しています。
hlsl
// RgbdParallax.shader(核心部分)
half4 frag(Varyings IN) : SV_Target
{
float2 uv = IN.uv;
// 視点オフセット(左端=-0.5, 右端=+0.5)
float viewOffset = (_LKG_ViewIndex / max(_LKG_NumViews - 1, 1)) - 0.5;
// 深度を取得
float depth = SAMPLE_TEXTURE2D(_DepthTex, sampler_DepthTex, uv).r;
if (_InvertDepth > 0.5) depth = 1.0 - depth;
// 視差シフト量 = 深度 × Depthiness × 視点オフセット + Focus
float parallax = (depth - 0.5) * _Depthiness * viewOffset
+ _Focus * viewOffset;
// UVシフト
float2 shiftedUV = clamp(uv + float2(parallax, 0.0), 0.0, 1.0);
return SAMPLE_TEXTURE2D(_ColorTex, sampler_ColorTex, shiftedUV);
}注意: _LKG_ViewIndex や _LKG_NumViews は LKG Plugin 4.0-alpha が各ビューレンダリング時に注入する変数です。プラグインのサンプルシェーダーで実際の変数名を確認してください。
方式B: 頂点変位シェーダー — SiNGRAY カメラプロジェクトで使用
高密度メッシュの各頂点を深度値に基づいてZ方向に変位させる手法です。
hlsl
// RGBDDisplacement.shader(核心部分)
Varyings vert(Attributes IN)
{
// 深度テクスチャを頂点シェーダー内でサンプリング
float depth = SAMPLE_TEXTURE2D_LOD(_MainTex, sampler_MainTex, depthUV, 0).r;
if (_DepthInvert > 0.5) depth = 1.0 - depth;
// 深度に基づいてZ軸方向に頂点を変位
float normalizedDepth = (depth - 0.5) + _Focus;
positionOS.z += normalizedDepth * _Depthiness;
OUT.positionHCS = TransformObjectToHClip(positionOS);
return OUT;
}方式の選定基準:
| 観点 | 視差シェーダー(方式A) | 頂点変位(方式B) |
|---|---|---|
| 処理速度 | ◎ 高速 | △ メッシュ解像度に依存 |
| 品質安定性 | ◎ 安定 | ○ エッジに「穴」が出る |
| 実装難易度 | ◎ 簡単 | △ メッシュ生成が必要 |
| 用途 | iPad版AM3D | SiNGRAYカメラリアルタイム |
シェーダーの LKG 対応必須事項
全シェーダーに以下のマクロが必須です:
hlsl
#pragma multi_compile_instancing
#pragma multi_compile _ STEREO_INSTANCING_ON
#pragma instancing_options renderinglayer
// 頂点シェーダーで:
UNITY_SETUP_INSTANCE_ID(IN);
UNITY_TRANSFER_INSTANCE_ID(IN, OUT);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);
// フラグメントシェーダーで:
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);これがないとマルチビューレンダリングで正しく各視点の画像が生成されません。
調整パラメータ
| パラメータ | 型 | 範囲 | デフォルト | 説明 |
|---|---|---|---|---|
| Focus | float | -1.0〜1.0 | 0.0(自動) | 焦点面位置。負=手前、正=奥 |
| Auto Focus | bool | ON/OFF | ON | フレーム中央深度でフォーカス自動追従 |
| Depthiness | float | 0.0〜3.0 | 1.0 | 立体感の強さ。0=平面、3=誇張 |
| FOV | float | 10°〜90° | 40° | 視野角 |
| Zoom | float | 0.5〜3.0 | 1.0 | 表示倍率 |
| Invert Depth | bool | ON/OFF | OFF | 深度の白黒を反転 |
| Background Mode | enum | AutoEdge/Solid | AutoEdge | 背景処理方法 |
Quilt MP4 エクスポート(目玉機能)
Quilt とは
Looking Glass は内部で「Quilt」という多視点画像集合体を使います。
Quilt(例: 48views、8列×6行)
┌─────────────────────────────────┐
│ view0 │ view1 │ ... │ view7 │
├───────┼───────┼─────┼──────────┤
│ view8 │ view9 │ ... │ view15 │
│ ... │ ... │ ... │ ... │
│view40 │view41 │ ... │ view47 │
└─────────────────────────────────┘エクスポートフロー
- 各フレームを一時停止しながら処理
- 1フレームごとに全視点(例: 48視点)をレンダリング
- Quilt レイアウトに並べて1枚のテクスチャにまとめる
- MediaEncoder / AVFoundation で MP4 に書き込み
- 音声を合成
- iOS Files / フォトライブラリに保存
デバイス別の推奨Quilt設定
| デバイス | ビュー数 | 列×行 | 1ビューサイズ | Quilt合計 |
|---|---|---|---|---|
| Portrait | 48 | 8×6 | 420×560 | 3360×3360 |
| 16" | 48 | 8×6 | 480×270 | 3840×1620 |
| Go | 48 | 8×6 | 210×280 | 1680×1680 |
AI補完
エクスポートの処理負荷: 48視点 × 全フレームのレンダリングは重い処理です。例えば 30fps × 60秒 = 1,800フレーム × 48視点 = 86,400回のレンダリングになります。対策として、エクスポート専用のFPS設定(低FPS)や視点数削減オプションの実装が推奨されます。処理中はバックグラウンドで進捗表示をつけることが重要です。
iOS 固有の実装事項
ファイルピッカー
csharp
// NativeFilePicker 推奨(https://github.com/yasirkula/UnityNativeFilePicker)
NativeFilePicker.PickFile(path => {
if (path == null) return;
StartCoroutine(LoadVideoFile(path));
}, new[] { "public.movie" });iOS キャリブレーション(初回設定)
Looking Glass Portrait に iPad を USB-C で接続した初回起動時:
- キャリブレーションファイルの選択を求められる
Locations → LKG-XXXXXX → LKG_calibration → visual.jsonを選択- 以降は自動ロード
キャッシュ戦略
Application.persistentDataPath/
└── RgbdCache/
├── {hash}.mp4 ← 変換済みRGBD SBS
└── {hash}.quilt.mp4 ← エクスポート済みQuilt元ファイルのパス+サイズのハッシュをキーにし、同じファイルの2回変換を防止します。
実装ロードマップ
Phase 1: 基盤
□ Unity プロジェクト作成(URP + LKG Plugin 4.0-alpha)
□ MultiView Example Scene の動作確認
□ RGBD SBS MP4 を VideoPlayer で再生し RenderTexture に書き込む
□ RgbdParallax.shader を実装
Phase 2: API連携
□ ApiClient.cs を実装
□ iOS ファイルピッカー → API送信 → RGBD SBS受信 → 表示
□ プログレス表示 + キャンセル機能
Phase 3: 表示品質
□ フォーカス自動追従
□ 背景色自動補完
□ パラメータUIパネル全実装
Phase 4: エクスポート
□ Quilt テクスチャ生成ロジック
□ MediaEncoder / AVFoundation でMP4書き出し
□ 音声合成
Phase 5: 仕上げ
□ キャッシュ機構
□ エラーハンドリング全ケース
□ iPad 実機テスト(Looking Glass Portrait 接続)実装上のハマりどころ
| 問題 | 対策 |
|---|---|
| LKG Plugin の変数名が不明 | Multiview Example Scene のシェーダーを分解して確認 |
| VideoPlayer + RenderTexture のGPU読み戻し | AsyncGPUReadback を使用 |
| MediaEncoder の iOS 制限 | AVFoundation ネイティブプラグインで代替 |
| iOS ネットワーク設定 | NSAppTransportSecurity の HTTPS 設定を確認 |
| Python版プレイヤーの教訓 | Bridge SDK の draw_interop_rgbd_texture_gl() はぼやける → 自前でRGBD→マルチビュー変換を行う |
参考リンク
| リソース | URL |
|---|---|
| LKG Plugin 4.0-alpha ドキュメント | https://docs.lookingglassfactory.com/software/index/unity-plugin-4.0-alpha |
| LKG Plugin 4.0 DL(Unity 6.0用) | https://look.glass/unity4-60-dl |
| LKG Plugin 4.0 DL(Unity 6.1用) | https://look.glass/unity4-61-dl |
| Looking Glass Bridge | https://look.glass/bridge |
| NativeFilePicker | https://github.com/yasirkula/UnityNativeFilePicker |
| NativeGallery | https://github.com/yasirkula/UnityNativeGallery |
| Video-Depth-Anything | https://github.com/DepthAnything/Video-Depth-Anything |
| Modal ダッシュボード | https://modal.com/apps/soichiro-xse/main/deployed/am3d-vda-api |
関連記事
- AM3D 概要 — プロジェクト全体像
- クラウド深度推定 API — API仕様(Unity C#実装例含む)
- LKG Bridge 不要レンダリング — レンチキュラーシェーダーの技術詳細
Author: 山本颯一郎 | Sources: UNITY_IPAD_APP_SPEC.md, HANDOFF_TO_MACBOOK.md, AI2AI引き継ぎ資料 AI Enhanced: Claude — 2026-03-06