WWDC Quick Look 💓 By SwiftGGTeam
Foveated Streaming で没入型コンテンツを visionOS へ届ける

Foveated Streaming で没入型コンテンツを visionOS へ届ける

元の動画を見る

ハイライト

Apple は visionOS 26.4 で Foveated Streaming フレームワークを導入し、Vision Pro が Wi-Fi 経由で PC 上の OpenXR コンテンツをワイヤレスストリーミングできるようにしました。システムはアイトラッキングを使って動的な注視点圧縮を行い、NVIDIA CloudXR プロトコルを内蔵しています。開発者は既存の OpenXR App を約1日で Vision Pro 上に持ち込めます。

主要内容

現実の痛点:PC 級 VR コンテンツがヘッドセット内に閉じ込められている

多くの没入型 App は PC の計算能力を必要とします。フライトシミュレーター、レーシングゲーム、産業向け 3D 可視化などでは、モデルの複雑さや物理計算量が一体型ヘッドセットの処理能力を大きく超えます。

以前の方法は、PC に VR ヘッドセットを接続し、ケーブルでつなぐことでした。ユーザーはコンピューターの近くに縛られ、動ける範囲が制限されます。コンテンツエコシステムも分断されます。OpenXR App は PC VR エコシステムで動きますが、visionOS の ARKit、SwiftUI、RealityKit といった機能は使えません。

Apple の答え:ワイヤレスストリーミングとシステムレベルの注視点最適化

Foveated Streaming は2つの問題を解決します。

第一に、ワイヤレスストリーミングです。visionOS は NVIDIA CloudXR SDK を内蔵し、PC と Vision Pro の間で Wi-Fi により映像と音声を送ります。家庭内 LAN でも、クラウド経由でも動かせます。

第二に、動的な注視点圧縮です。Vision Pro のアイトラッキングハードウェアは、ユーザーがどこを見ているかをリアルタイムに把握します。システムは視線中心を高解像度で転送し、周辺視野は精度を下げます。圧縮ロジックは visionOS が完全に処理するため、開発者が介入する必要はありません。

(00:26)

既存 App がこの方向性を実証している

Laminar Research はこの仕組みで、PC 向けフライトシミュレーター X-Plane 12 を Vision Pro へ持ち込んでいます。visionOS 側の App は ARKit で物理コックピットの位置を認識し、ストリーミングされた仮想映像を実機器と位置合わせします。ユーザーは自分の手が本物の操縦桿を握っているのを見ながら、目の前に完全な仮想コックピットと窓外の景色を見られます。

iRacing のレーシングシミュレーターも同じ方法を使っています。ARKit のハンドトラッキングで実物のハンドル位置を仮想コックピットへ同期し、ユーザーが下を見ると、自分の手が仮想ハンドルを握っているように見えます。

Autodesk VRED は Innoactive の統合を通じて Vision Pro に入ります。Kia のデザイナーはこれを使い、実寸大で自動車モデルを確認し、エンジニアリングレベルの細部まで見ています。

(01:04)

単なるストリーミングではなく、visionOS ネイティブ機能と混ぜられる

Foveated Streaming は単なる「動画プレイヤー」ではありません。ストリーミングコンテンツは、SwiftUI インターフェイス、RealityKit レンダリング、ARKit の空間認識と重ねて使えます。

たとえば、ストリーミングされた OpenXR ゲーム映像の上に、SwiftUI で作ったステージ選択メニューを置けます。メニューはネイティブ visionOS コントロールで、空間ジェスチャーに対応します。ユーザーがステージを選ぶと、Message Channel 経由で PC 側の OpenXR App へ指示を送れます。

(03:13)

詳細

システム構成:両側で何が必要か

システムは2つの部分で構成されます。

  • PC 側(Streaming Endpoint):OpenXR App + NVIDIA CloudXR Runtime + Apple Foveated Streaming Protocol 実装
  • Vision Pro 側(Receiver App)FoveatedStreaming フレームワークを使って接続し、コンテンツを表示し、visionOS ネイティブ機能と統合する

(04:10)

Apple は GitHub で完全なエンドツーエンドのサンプルコードを提供しています。Windows 側のプロトコル参照実装と OpenXR サンプル App も含まれます。ドキュメントに従えば、午後のうちに全体の経路をつなげられます。

接続の確立:Session 型 API

visionOS 側の中心クラスは FoveatedStreamingSession です。

import SwiftUI
import FoveatedStreaming

struct ConnectView: View {
    let session: FoveatedStreamingSession

    var body: some View {
        Button("接続") {
            Task {
                try await session.connect()
            }
        }
    }
}

(06:03)

重要ポイント:

  • FoveatedStreamingSession は session-based API の入口です
  • connect() は非同期メソッドで、ペアリングと接続の全体フローを内部で処理します
  • 呼び出し後、フレームワークはローカルネットワーク内の利用可能な endpoint を自動スキャンします
  • Vision Pro と endpoint が初回ペアリングする時、PC 側に QR コードが表示され、ユーザーは視線でスキャンしてペアリングを完了します

ImmersiveSpace でストリーミングコンテンツを表示する

接続が確立したら、session を ImmersiveSpace に渡すだけでストリーミング映像を表示できます。

import SwiftUI
import FoveatedStreaming

@main struct FoveatedStreamingSampleApp: App {
    private let session = FoveatedStreamingSession()

    var body: some SwiftUI.Scene {
        ImmersiveSpace(foveatedStreaming: session)
    }
}

(06:44)

重要ポイント:

  • ImmersiveSpace(foveatedStreaming:) は SwiftUI が Foveated Streaming 向けに提供する専用 initializer です
  • 動画テクスチャやレンダリングループを手動管理する必要はありません。フレームワークが内部で処理します
  • ストリーミングコンテンツは ImmersiveSpace の下地映像になり、その上に SwiftUI や RealityKit コンテンツを重ねられます

SwiftUI コンテンツを混ぜる

実際の App では、ストリーミング映像の上にネイティブ UI を重ねることがよくあります。

import SwiftUI
import FoveatedStreaming

@main struct FoveatedStreamingSampleApp: App {
    private let session = FoveatedStreamingSession()
    private let appModel = AppModel()

    var body: some SwiftUI.Scene {
        Window("メイン", id: appModel.mainWindowId) {
            ContentView(session: session)
                .environment(appModel)
                .environment(session)
        }

        ImmersiveSpace(foveatedStreaming: session) {
            SpatialContainer {
                ReopenMainWindowView().environment(appModel)
                TransformStreamWidgetView().environment(session)
            }
        }
    }
}

(06:55)

重要ポイント:

  • Window シーンは独立して存在でき、メインメニュー、一時停止/再開コントロールなどに使えます
  • ImmersiveSpace 内では SpatialContainer が複数の SwiftUI View を包みます
  • ReopenMainWindowView は ImmersiveSpace 内で「メインウィンドウを再度開く」コントロールを提供する例です
  • TransformStreamWidgetView は session 状態へアクセスし、接続情報やデバッグデータを表示できます
  • progressive immersion など、すべての SwiftUI 没入スタイルをサポートします

RealityKit コンテンツを混ぜる

ストリーミング映像の上に 3D オブジェクトを重ねたい場合は、RealityView を使います。

import SwiftUI
import RealityKit
import FoveatedStreaming

@main struct FoveatedStreamingSampleApp: App {
    private let session = FoveatedStreamingSession()
    private let appModel = AppModel()

    var body: some SwiftUI.Scene {
        ImmersiveSpace(foveatedStreaming: session) {
            RealityView { content in
                // ここに RealityKit エンティティを追加する
            }
        }
    }
}

(13:42)

重要ポイント:

  • RealityView とストリーミングコンテンツは、同じ ImmersiveSpace 内で自動合成されます
  • OpenXR App が深度バッファと alpha チャンネルを提供する場合、RealityKit オブジェクトとストリーミングオブジェクトは正しく遮蔽し合えます
  • これは、手や机の位置など物理世界の ARKit データと、ストリーミングされた仮想コンテンツを融合するための重要な仕組みです

PC 側プロトコル:Foveated Streaming Protocol

PC 側は Apple が定義する Foveated Streaming Protocol を実装する必要があります。これは映像ストリームとは独立した軽量 TCP 接続で、認証と状態同期を担当します。

プロトコルメッセージは JSON でエンコードされ、request-acknowledge パターンを使います。

  1. Vision Pro が接続リクエストを開始する
  2. 未ペアリングの場合、pairing barcode を要求する
  3. Barcode には client token と接続証明書ハッシュ(NVIDIA CloudXR SDK が提供)が含まれる
  4. ペアリング完了後、endpoint がコンテンツ準備完了を報告し、映像ストリームが始まる

(08:30)

状態管理で注意すべき点:

  • ユーザーが Vision Pro を外してスリープに入ると、システムは endpoint にストリーミング停止を通知します
  • スリープ中はすべての接続が切断されます
  • ユーザーが再び装着した時に再接続できるよう、endpoint は利用可能な状態を保つ必要があります

入力データは自動的に透過される

Vision Pro のハンドトラッキング、コントローラー位置、マイクデータは、CloudXR を通じて自動的に OpenXR 入力へマッピングされます。PC 側の OpenXR App は追加対応を必要としません。

具体的なサポート:

  • OpenXR Hand Tracking 拡張
  • PlayStation VR2 Sense コントローラー
  • コントローラーとハンドトラッキングデータは内蔵対応で、追加コードは不要

Apple は、最高の体験のために OpenXR App が深度バッファ(depth buffer)と alpha チャンネルを提供することを推奨しています。

(10:40)

Message Channel:両端の通信

Foveated Streaming フレームワークは Message Channel API を提供し、visionOS App と PC 側 OpenXR App の双方向通信を可能にします。

visionOS 側では FoveatedStreamingSession の message channel API からデータを送ります。PC 側では CloudXR が提供する OpenXR 拡張で受け取ります。メッセージ内容は純粋なバイナリデータで、形式は App が自由に定義します。

典型的な用途:

  • visionOS 側の SwiftUI メニューで選択した後、ステージ読み込み指示を送る
  • PC 側から読み込み進捗を返す
  • visionOS 側で ARKit を使って物理空間の位置を取得し、message channel で PC へ同期して、仮想コンテンツと実環境を位置合わせする

FoveatedStreamingSession は OpenXR 座標系と ARKit 座標系の変換 API も提供します。

(12:06)

パフォーマンスデバッグツール

Xcode は Foveated Streaming Instrument を提供し、次の項目を測定できます。

  • ストリーミング帯域幅
  • Pose latency(姿勢遅延)
  • フレームレート

このツールを使うことで、ストリーミング体験のパフォーマンス問題を診断できます。

(11:34)

重要な示唆

既存の PC VR ゲームを Vision Pro へ移植する

何を作るか:OpenXR ベースの PC VR ゲームや App がすでにあるなら、約1日で Vision Pro 上にワイヤレス実行できます。

なぜ価値があるか:Vision Pro の表示解像度とアイトラッキング精度は、多くの PC VR ヘッドセットを大きく上回ります。そこにワイヤレスの自由度と visionOS ネイティブ UI を加えると、体験は大きく向上します。

どう始めるか:Apple GitHub 上の StreamingSession サンプルをダウンロードし、Windows 側のプロトコル参照実装を自分の OpenXR App に組み込みます。visionOS 側は sample code をもとに UI を変更します。

物理機器 + 仮想映像の混合シミュレーター

何を作るか:X-Plane 12 の方法を参考に、ステアリングホイール、フライトヨーク、楽器などの物理周辺機器を使うシミュレーション App を作ります。実機器は ARKit が認識し、仮想映像は PC からストリーミングします。

なぜ価値があるか:この種の App は物理インタラクションの fidelity への要求が高く、一体型ヘッドセットの計算能力だけでは足りません。Foveated Streaming により、PC はレンダリングを担当し、Vision Pro は空間認識と表示を担当します。それぞれ得意なことを分担できます。

どう始めるか:ARKit の平面検出と Object Tracking で物理周辺機器を定位し、Message Channel で座標を PC 側 OpenXR App へ同期します。FoveatedStreamingSession には既存の座標系変換 API があります。

工業デザインレビュー工具

何を作るか:Autodesk VRED の統合を参考に、デザイナーが大型 3D モデルを実寸大で確認できるツールを作ります。モデルは PC 上でレンダリングし、Vision Pro は表示と空間定位を担当します。

なぜ価値があるか:自動車、建築、航空宇宙領域の CAD モデルは通常数十 GB あり、ヘッドセット上へ直接読み込めません。PC 側にはプロ向け GPU と十分なメモリがあるため、ストリーミングが合理的です。

どう始めるか:PC 側で OpenXR を使って CAD モデルを読み込み、visionOS 側では ARKit で会議室や展示室の床と壁を認識します。Message Channel で空間アンカーを同期し、モデルが実際の床に「立つ」ようにします。

複数人協業の混合現実会議室

何を作るか:クラウド PC からストリーミングされた共有 3D シーンを Vision Pro 上に表示します。各参加者は自分の Vision Pro で同じ内容を見ますが、視点は独立しています。

なぜ価値があるか:クラウド PC は都市規模のデジタルツインのような超大規模シーンをレンダリングでき、複数の Vision Pro が同時に接続できます。各ユーザーのアイトラッキングは自分の映像だけを独立して最適化するため、互いに干渉しません。

どう始めるか:クラウドに NVIDIA CloudXR サーバーを配置し、各 Vision Pro で Foveated Streaming receiver App を実行します。Message Channel でユーザー位置とインタラクションを同期します。

5. SwiftUI オーバーレイでストリーミングゲームの HUD とメニューを作る

何を作るか:ストリーミングされた OpenXR ゲーム映像の上に、SwiftUI でステージ選択、設定パネル、フレンドリストなどの UI 層を構築します。ネイティブ SwiftUI コントロールは空間ジェスチャーをサポートし、ストリーミング映像と自然に融合します。

なぜ価値があるか:純粋な OpenXR App の UI は自前描画テクスチャで実装されることが多く、Vision Pro 上では違和感が出がちです。SwiftUI オーバーレイを使えば visionOS のデザイン言語に合う UI を作れ、Message Channel でユーザー操作を PC 側ゲームへ送れます。

どう始めるかImmersiveSpace(foveatedStreaming: session) の内部で SpatialContainer に SwiftUI View を包みます。ボタンがタップされたら、FoveatedStreamingSession の message channel API で PC 側へバイナリ指示を送ります。

関連 Session

コメント

GitHub Issues · utterances