Search code examples
swiftswiftuiscenekitskybox

SceneKit – Loading HDR or EXR lightingEnvironment has no effect


I tried loading an .hdr file to use it as a skybox and use its lighting informations. This is the code I used:

backgroundColor = UIColor.gray 
// check if a default skybox is added

let environment = UIImage(named: "studio_small_09_2k.hdr")
scene?.lightingEnvironment.contents = environment
scene?.lightingEnvironment.intensity = 1.0
scene?.background.contents = environment

Unfortunately I recieve a grey screen and also no errors. Has anyone experience in using hdr files in SceneKit?

XCode Version: 13.2.1 iOS version: 15.3.1 hdr file: https://polyhaven.com/a/studio_small_09


Solution

  • I usually use a Cube Texture Set, where each of 6 images is square (height == width).

    Also, the following cube map representations are supported:

    • Vertical strip as single image (height == 6 * width)
    • Horizontal strip as single image (6 * height == width)
    • Spherical projection as single image (2 * height == width)

    Here's a SwiftUI code:

    func makeUIView(context: Context) -> SCNView {
    
        let sceneView = SCNView(frame: .zero)
        sceneView.scene = SCNScene()
        // if EXR or HDR is 2:1 spherical map, it really meets the requirements
        sceneView.scene?.lightingEnvironment.contents = UIImage(named: "std.exr")
        sceneView.backgroundColor = .black
        sceneView.autoenablesDefaultLighting = true
        sceneView.allowsCameraControl = true
        
        let node = SCNNode()
        node.geometry = SCNSphere(radius: 0.1)
        node.geometry?.firstMaterial?.lightingModel = .physicallyBased
        node.geometry?.firstMaterial?.metalness.contents = 1.0
        sceneView.scene?.rootNode.addChildNode(node)
        return sceneView
    }
    

    Pay particular attention – you need .physicallyBased lighting model to get HDR or EXR reflections.

    enter image description here

    And let's set it for BG:

    sceneView.scene?.background.contents = UIImage(named: "std.exr")
    

    enter image description here


    Why your .exr doesn't work?

    The solutions is simple: delete your .exr from project, empty the Trash and after that drag-and-drop .exr file, in Choose options for adding these files window choose Add to targets:

    enter image description here

    Now your .exr must work.