在visionOS中当前窗口后面渲染(理想弯曲的)背景图像

问题描述 投票:0回答:1

到目前为止,我成功地从我的主

ImmersiveSpace
中打开了一个
Window
,它将图像渲染为像这样的平面纹理。-

var body: some View {
    ZStack {
        RealityView { content in
                    
            var material = UnlitMaterial()
            material.color = try! .init(tint: .white,
                                     texture: .init(.load(named: "image",
                                                             in: nil)))
        
            let entity = Entity()
            let component = ModelComponent(
                mesh: .generatePlane(width: 1, height: 1),
                materials: [material]
            )
            entity.components.set(component)
            
            entity.scale *= .init(x: 1, y: 1, z: 1)
            
            let currentTransform = entity.transform
            var newTransform = Transform(scale: currentTransform.scale,
                                         rotation: currentTransform.rotation,
                                         translation: SIMD3(0, 0, -0.3))
            entity.move(to: newTransform, relativeTo: nil)
            
            /*
            let scalingPivot = Entity()
            scalingPivot.position.y = entity.visualBounds(relativeTo: nil).center.y
            scalingPivot.addChild(entity)
            content.add(scalingPivot)
            
            scalingPivot.scale *= .init(x: 1, y: 1, z: 1)
            */
        }
    }
}

但我无法将其移到

z-axis
深处以将其显示在窗口后面(如果我设置的值小于-0.4,它就会消失)。

此外,我尝试了多种缩放方式,以便背景图像显示得比窗口大,但任何缩放操作似乎只影响纹理坐标,而不影响平面网格本身。

最后,我希望理想地在曲面中渲染此图像(非常类似于 180% 全景图像)。作为第一种方法,我找到了 this 教程来创建弯曲的墙,但似乎箭头对象在

Reality Composer Pro
上不再可用。

也欢迎任何关于在主窗口后面渲染背景图像的不同方法的建议/提示:)

augmented-reality reality-composer visionos
1个回答
0
投票

如果您在

ImmersiveSpace
,您可以使用 Apple 的“DestinationVideo”中的
addSkybox

在您的

App
文件中

@main
struct SimpleVideoPlayerApp: App {
    @Environment(\.openImmersiveSpace) var openImmersiveSpace
    var body: some Scene {
        WindowGroup {
            Text("Hello World!")
        }
        
        ImmersiveSpace(id: "ImmersiveSpace") {
            SkyboxView()
        }.immersionStyle(selection: .constant(.progressive), in: .progressive)
    }
}

然后在另一个文件中

#if os(visionOS)
import SwiftUI
import RealityKit
import Combine
struct SkyboxView: View {
    var body: some View {
        RealityView { context in
            let entity = Entity()
            entity.addSkybox(for: "beach_scene", rotation: .degrees(55))
            context.add(entity)
        }
    }
}

extension Entity {
    func addSkybox(for name: String, rotation: Angle) {
        let subscription = TextureResource.loadAsync(named: name).sink(
            receiveCompletion: {
                switch $0 {
                case .finished: break
                case .failure(let error): assertionFailure("\(error)")
                }
            },
            receiveValue: { [weak self] texture in
                guard let self = self else { return }
                var material = UnlitMaterial()
                material.color = .init(texture: .init(texture))
                self.components.set(ModelComponent(
                    mesh: .generateSphere(radius: 1E3),
                    materials: [material]
                ))
                self.scale *= .init(x: -1, y: 1, z: 1)
                self.transform.translation += SIMD3<Float>(0.0, 1.0, 0.0)
                
                // Rotate the sphere to show the best initial view of the space.
                print("rotate")
                updateRotation(for: rotation)
            }
        )
        components.set(Entity.SubscriptionComponent(subscription: subscription))
    }
    
    func updateRotation(for rotation: Angle) {
        // Rotate the immersive space around the Y-axis set the user's
        // initial view of the immersive scene.
        let rotation = simd_quatf(angle: Float(rotation.radians), axis: SIMD3<Float>(0, 1, 0))
        self.transform.rotation = rotation
    }
    
    /// A container for the subscription that comes from asynchronous texture loads.
    ///
    /// In order for async loading callbacks to work we need to store
    /// a subscription somewhere. Storing it on a component will keep
    /// the subscription alive for as long as the component is attached.
    struct SubscriptionComponent: Component {
        var subscription: AnyCancellable
    }
}

https://developer.apple.com/documentation/visionos/destination-video

© www.soinside.com 2019 - 2024. All rights reserved.