Apple Vision Pro Metal版 (visionOS) Fully Immersive Space のサンプルアプリを動かしてみる  | 技術ブログ | 株式会社OnePlanet 読み込まれました

Apple Vision Pro Metal版 (visionOS) Fully Immersive Space のサンプルアプリを動かしてみる

はじめに

RealityKitでなく、Metalを使ったFully Immersive、完全没入型のアプリを開発する上でSwiftUIからMetalの架け橋となる部品を使用する必要があります。今回はGithubにあるサンプルプロジェクトを使ってポイントだけ説明したいと思います。

Apple Vision Pro について

Apple Vision Pro について、以下の記事にまとめてます。

Fully Immersive Metal プロジェクトの入手

https://github.com/metal-by-example/metal-spatial-rendering

githubに公開しているmetal-spatial-renderingプロジェクトをダウンロードします。

Fully Immersive Metal プロジェクトをXCodeにインポート

Fully Immersive Metal プロジェクトをXcodeから開きます。

App.swift

import SwiftUI
import CompositorServices

struct MetalLayerConfiguration: CompositorLayerConfiguration {
    func makeConfiguration(capabilities: LayerRenderer.Capabilities,
                           configuration: inout LayerRenderer.Configuration)
    {
        let supportsFoveation = capabilities.supportsFoveation
        //let supportedLayouts = capabilities.supportedLayouts(options: supportsFoveation ? [.foveationEnabled] : [])
        configuration.layout = .dedicated
        configuration.isFoveationEnabled = supportsFoveation
        configuration.colorFormat = .rgba16Float
    }
}

@main
struct FullyImmersiveMetalApp: App {
    var body: some Scene {
        WindowGroup {
            ContentView()
        }

        ImmersiveSpace(id: "ImmersiveSpace") {
            CompositorLayer(configuration: MetalLayerConfiguration()) { layerRenderer in
                SpatialRenderer_InitAndRun(layerRenderer)
            }
        }.immersionStyle(selection: .constant(.full), in: .full)
    }
}

CompositorLayerConfiguration 

Metalレンダリングエンジンで使用するテクスチャ設定とレンダリングを指定するための設定プロトコルです。

https://developer.apple.com/documentation/compositorservices/drawingfullyimmersivecontentusing_metal#4198157

https://developer.apple.com/documentation/compositorservices/compositorlayerconfiguration

CompositorLayer

完全な没入モードに切り替わると ImmersiveSpace が呼び出されます。
ImmersiveSpace のコンテンツをMetalを使ってレンダリングする場合は、CompositorLayerを使って指定する必要があります。

https://developer.apple.com/documentation/compositorservices/compositorlayer

ContentView.swift

import SwiftUI
import RealityKit

struct ContentView: View {
    @State var showImmersiveSpace = false
    
    @Environment(\.openImmersiveSpace) var openImmersiveSpace
    @Environment(\.dismissImmersiveSpace) var dismissImmersiveSpace
    
    var body: some View {
        VStack {
            Toggle(showImmersiveSpace ? "Exit Immersive Space" : "Launch Immersive Space", isOn: $showImmersiveSpace)
                .toggleStyle(.button)
        }
        .padding()
        .onChange(of: showImmersiveSpace) { _, newValue in
            Task {
                if newValue {
                    await openImmersiveSpace(id: "ImmersiveSpace")
                } else {
                    await dismissImmersiveSpace()
                }
            }
        }
    }
}

トグルをタップするとopenImmersiveSpaceが呼び出します。App.swiftのImmersiveSpaceに処理が進み、Metalによる完全没入モードに切り替わります。

SpatialRenderingEngine.mm

void SpatialRenderer_InitAndRun(cp_layer_renderer_t layerRenderer) {
    RenderThread *renderThread = [[RenderThread alloc] initWithLayerRenderer:layerRenderer];
    renderThread.name = @"Spatial Renderer Thread";
    [renderThread start];
}

上記コードは、抜粋してます。レンダリングループ用のスレッドを起動します。代わりに、LayerRenderer タイプの状態をチェックして、シーンが実際に実行されているかどうかを確認します。

https://developer.apple.com/documentation/compositorservices/drawingfullyimmersivecontentusing_metal#4193611


実行

はじめはShared Space上で表示しているWindowのトグルをタップすると空間が完全没入モードに切り替わります。


まとめ

RealityKitとMetalでは、Fully Immersiveによる完全没入までの実装方法が異なっているため、各々の特徴を理解しながら開発を進めていく必要があります。

XR エンジニア

徳山 禎男

SIerとして金融や飲料系など様々な大規模プロジェクトに参画後、2020年にOnePlanetに入社。ARグラスを中心とした最先端のAR技術のR&Dや、法人顧客への技術提供を担当。過去にMagic Leap 公式アンバサダーを歴任。

View More

お問い合わせ・ご相談

ARでやってみたいことやお困りごとなど
お気軽にお問い合わせください。

お問い合わせ