Alexander Garcia
Alexander Garcia

Reputation: 11

Add blur transition as skybox Entity is removed or added for Vision Pro

I'm trying to build a small Vision app similar to Zillow's immersive home tour. I'm using an UnlitMaterial and adding a static image texture as the material color. If a user changes the room I remove the old skybox entity in the RealityView update closure and replace it with a new one as I want them to remain in the full immersion but just change the texture. I tried adding animation / transition modifiers to the view but so far unsuccessful. In the update closure since that is what is triggered when the user makes a change I tried to retrieve the old entity and modify the texture to the image but also been unsuccessful. Is my architecture incorrect to achieve this?

Question: Is it possible to add a blur transition when adding or removing entities to the content within RealityView similar to the blur found in Zillow's immersive app as a user changes rooms?

struct ImmersiveView: View {
    @Binding var selectedRoom: String
    
    var body: some View {
        RealityView { content in
            guard let skybox = createSkybox() else { return }
            
            content.add(skybox)
        } update: { content in
            let _ = print(content.entities[0])
            // remove previous entities
            content.entities.removeAll()
            // add a new skybox
            guard let skybox = createSkybox() else { return }
            content.add(skybox)
        }
    }
    
    private func createSkybox () -> Entity? {
        // create mesh
        let skyBoxMesh = MeshResource.generateSphere(radius: 1000)
        
        // image material
        guard let imageMaterial = createMaterial() else { return nil }
        
        // create entity
        let skyboxEntity = Entity()
        skyboxEntity.components.set(
            ModelComponent(
                mesh: skyBoxMesh,
                materials: [imageMaterial]
            )
        )

        // map texture to inner surface
        skyboxEntity.scale *= .init(x: -1, y: 1, z: 1)
        
        return skyboxEntity
    }
    
    private func createMaterial () -> UnlitMaterial? {
        var material = UnlitMaterial()
        
        do {
            let texture = try TextureResource.load(named: selectedRoom)
            material.color = .init(texture: .init(texture))

        } catch {
            print("Error loading image \(error)")
        }

        return material
    }
}

Upvotes: 1

Views: 169

Answers (1)

Hal Mueller
Hal Mueller

Reputation: 7646

In my own work I've found it impossible to modify a Material that's driven by a TextureResource. I have to make a new Material and MeshResource instances.

Could you solve your problem by using two skyboxes, or even three? Add one for the blur at radius 999, animate the old one's radius out beyond 1000, add the new one behind the blur?

Upvotes: 0

Related Questions