skip to Main Content

Does anyone knows how to clear the background of a SceneView 3D Object? I’m trying using UIColor.clear, but it makes it white.
[This should be clear, but it's white]

import SwiftUI
import SceneKit

struct TestView: View {
    var body: some View {
    
        ZStack{
                    Color.green
                    SceneView(
                        scene: {
                            let scene = SCNScene(named: "Earth.scn")!
                            scene.background.contents = UIColor.clear
                            return scene
                        }(),
                        options: [.autoenablesDefaultLighting,.allowsCameraControl]
                    )
                    .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height/2, alignment: .center)
                
                }
    }
}

struct TestView_Previews: PreviewProvider {
    static var previews: some View {
        TestView()
    }
}

2

Answers


  1. Here’s a solution that worked for me, mostly adopted from the answers here:

    import SceneKit
    import SwiftUI
    
    final class EarthSceneView: UIViewRepresentable {
        typealias UIViewType = SCNView
        typealias Context = UIViewRepresentableContext<EarthSceneView>
    
        func updateUIView(_ uiView: UIViewType, context: Context) {}
        func makeUIView(context: Context) -> UIViewType {
            let view = SCNView()
            view.backgroundColor = UIColor.clear // this is key!
            view.allowsCameraControl = true
            view.autoenablesDefaultLighting = true
            // load the scene here, could load an .obj file too
            view.scene = SCNScene(named: "Earth.scn")!
            return view
        }
    }
    

    Then you can use it in your view as:

    import SwiftUI
    
    struct TestView: View {
        var body: some View { 
            ZStack{
                Color.green
                EarthSceneView()
                    .frame( // set frame as required
                        maxWidth: .infinity,
                        maxHeight: .infinity,
                        alignment: .center
                    )
            }
        }
    }
    
    struct TestView_Previews: PreviewProvider {
        static var previews: some View {
            TestView()
        }
    }
    
    Login or Signup to reply.
  2. I know that I’m late, but here is a refined approach described in the other answers:

    struct TestView: View {
        var body: some View {
            ZStack {
                Color.green
                LegacySceneView(scene: {
                        let scene = SCNScene()
                        scene.background.contents = UIColor.clear
                        return scene
                    }(), options: [.autoenablesDefaultLighting,.allowsCameraControl]
                )
                .frame(width: UIScreen.main.bounds.width, height: UIScreen.main.bounds.height/2, alignment: .center)
            }
        }
    }
    
    struct LegacySceneView: UIViewRepresentable {
        var scene: SCNScene
        var options: SceneView.Options
        
        func makeUIView(context: Context) -> SCNView {
            let view = SCNView()
            view.backgroundColor = UIColor.clear
            view.allowsCameraControl = options.contains(.allowsCameraControl)
            view.autoenablesDefaultLighting = options.contains(.autoenablesDefaultLighting)
            view.rendersContinuously = options.contains(.rendersContinuously)
            view.isJitteringEnabled = options.contains(.jitteringEnabled)
            view.isTemporalAntialiasingEnabled = options.contains(.temporalAntialiasingEnabled)
            view.scene = scene
            return view
        }
        
        func updateUIView(_ uiView: SCNView, context: Context) { }
    }
    
    

    You just need to replace the SceneView to LegacySceneView. No other changes are required. Enjoy!

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search