2023/9/6
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/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 タイプの状態をチェックして、シーンが実際に実行されているかどうかを確認します。
実行
はじめはShared Space上で表示しているWindowのトグルをタップすると空間が完全没入モードに切り替わります。
まとめ
RealityKitとMetalでは、Fully Immersiveによる完全没入までの実装方法が異なっているため、各々の特徴を理解しながら開発を進めていく必要があります。
XR エンジニア
徳山 禎男
SIerとして金融や飲料系など様々な大規模プロジェクトに参画後、2020年にOnePlanetに入社。ARグラスを中心とした最先端のAR技術のR&Dや、法人顧客への技術提供を担当。過去にMagic Leap 公式アンバサダーを歴任。
View More