Lab 012 – Playing with Occlusion, Anchors, and Gestures

In this lab I combined some gestures, a hand anchor, and an entity with an occlusion material.

Playing with occlusion material is a ton of fun. This lab don’t aim to teach anything, I was just building something for sake of it.

I used the SkyDome from Reality Composer Pro and adjusted the colors on the materials. Then I added a sphere with an occlusion material and the components needed for gestures.

  • Drag the sphere around the scene
  • Scale it with the magnify gesture
  • Double-tap it to anchor it to the left hand
  • Double-tap again to reset it

I may add to this lab over time, or just duplicate it for future ideas.

Later in the afternoon I made a few changes

  • Added a glass object around the occlusion entity
  • Toggle between opaque and transparent to reveal the occlusion entity
  • Set up a spinning cube to explore another shape
struct Lab012: View {

    @State var leftHandTrackedEntity: Entity = {
        let handAnchor = AnchorEntity(.hand(.left, location: .palm))
        return handAnchor
    }()

    @State var rightHandTrackedEntity: Entity = {
        let handAnchor = AnchorEntity(.hand(.right, location: .palm))
        return handAnchor
    }()

    @State var orbIsActive: Bool = false

    var body: some View {
        RealityView { content, attachments in

            if let scene = try? await Entity(named: "Lab012Scene", in: realityKitContentBundle) {
                content.add(scene)
                content.add(leftHandTrackedEntity)
                content.add(rightHandTrackedEntity)
                

            }

        } update: { content, attachments in

        } attachments: {

        }
        .persistentSystemOverlays(.hidden)
        .gesture(tapGesture)
        .gesture(longPressGesture)
        .modifier(DragGestureImproved())
        .modifier(MagnifyGestureImproved())

    }

    var tapGesture: some Gesture {
        TapGesture(count: 2)
            .targetedToAnyEntity()

            .onEnded { value in
                

                let subject = value.entity
                subject.scale = .init(repeating: 1.0)

                if(value.entity.parent == leftHandTrackedEntity) {
                    // Move the subject from the anchor to the scene root
                    leftHandTrackedEntity.parent?.addChild(subject)
                    leftHandTrackedEntity.removeChild(subject)
                    // Set position back to default
                    subject.position = [1, 1, -1]

                } else {
                    // Attach the subject to the anchor
                    leftHandTrackedEntity.addChild(subject)
                    subject
                        .setPosition(
                            [0.12, 0.12, 0],
                            relativeTo: leftHandTrackedEntity
                        )
                }
            }
    }

    // A long press gesture that will toggle the opacity of the subject material
    var longPressGesture: some Gesture {
        LongPressGesture()
            .targetedToAnyEntity()
            .onEnded { value in
                let subject = value.entity

                orbIsActive.toggle()

                if var emitter = subject.components[ParticleEmitterComponent.self] {
                    emitter.isEmitting = !orbIsActive
                    subject.components[ParticleEmitterComponent.self] = emitter
                }

                if var mat = subject.components[ModelComponent.self]?.materials.first as? PhysicallyBasedMaterial {
                    mat.blending = .transparent(opacity: orbIsActive ? 0.2 : 1.0)
                    subject.components[ModelComponent.self]?.materials[0] = mat
                }

            }
    }

}

Video Demo

A video demo. A sphere is attached to the left hand, the right hand uses a gesture to swap the material to Occlusion

Support our work so we can continue to bring you new examples and articles.

Questions or feedback?