Lab 017 – Exploring a Skybox Material with Shader Graph

Swapping a Skybox Material and an Occlusion Material to jump between worlds.

Over the weekend I asked on Bluesky about the possibility of creating a living moving skybox material in RealityKit. Several folks had ideas and @dreamwieber.bsky.social even stepped up with a tutorial.

Maybe I should do a video at some point on something like cloud shaders specifically 🤔You can get something basic going quickly if you use the fractal noise node,

Gregory (@dreamwieber.bsky.social) 2024-12-08T15:09:29.784Z

This was a great prompt – video is live!bsky.app/profile/drea…

Gregory (@dreamwieber.bsky.social) 2024-12-08T23:03:14.238Z

You should definitely watch the full video on YouTube. As someone with no background in shaders, I found it immensely helpful. Looking at completed shaders or graphs hasn’t been useful to me. Seeing Gregory assemble this node by node while talking through it was just what I needed.

My version of the Shader is more or less a copy of the one in the video. I’ve adjusted some of the parameters and colors but the nodes are the same.

Video Demo

Lab Code

This lab just just a few things

  • Load a scene from the RealityKitContent bundle
  • Add a tap gesture to toggle the sky from a small sphere to a skybox sphere
  • The update closure will take care of the swap. This is a bit of a hack. I just swapped their scales and match their positions.
struct Lab017: View {

    @State var showSkyLarge: Bool = false

    var body: some View {
        RealityView { content in

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

        } update: {content in

            guard let root = content.entities.first else { return }
            if let skySphere = root.findEntity(named: "SkySphere"), let occSphere = root.findEntity(named: "OccSphere") {

                skySphere.scale = showSkyLarge ? [10, 10, 10] : [0.5, 0.5, 0.5]
                occSphere.scale = showSkyLarge ? [0.5, 0.5, 0.5] : [10, 10, 10]

                if(showSkyLarge) {
                    occSphere.position = skySphere.position
                } else {
                    skySphere.position = occSphere.position
                }

            }

        }
        .gesture(tap)
        .modifier(DragGestureImproved())

    }

    var tap: some Gesture {
        TapGesture()
            .targetedToAnyEntity()
            .onEnded {_ in
                showSkyLarge.toggle()
            }
    }
}

I’m thankful to Gregory for getting me started with Shader Graph. I have a lot to learn and explore and I’m excited to see what I can build with it.

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

Download the Xcode project with this and many more labs from Step Into Vision.

Questions or feedback?