Face order for SCNMaterialProperty contents?

The documentation lists the face order of cube maps like this:

+X, -X, +Y, -Y, +Z, -Z


But using this order in a cube map SCNScene.lightingEnvironment.contents and .background.contents will result in +Z and -Z being wrong, the other faces are correct.


Here is an example command line program that demonstrates this. It will load and use one of the (low res) images from the documentation page, and save a snapshot of the scene to ~/Desktop/test.png.


import SceneKit


func renderTestSceneToDesktop() {


    // Setup the scene:
    let scene = SCNScene()
    scene.lightingEnvironment.contents =
        URL.init(string:
            "https://docs-assets.developer.apple.com/published/cac6f9be44/scenekitcubemap_row_2x_fc38741d-bcd9-4c53-9854-6077c3ea9635.png")
    
    scene.background.contents = scene.lightingEnvironment.contents
    
    let sphereNode = SCNNode()
    let sphereGeom = SCNSphere(radius: 0.5)
    sphereGeom.segmentCount = 48
    sphereNode.geometry = sphereGeom
    sphereNode.geometry!.firstMaterial!.lightingModel = .physicallyBased
    sphereNode.geometry!.firstMaterial!.diffuse.contents = 1
    sphereNode.geometry!.firstMaterial!.metalness.contents = 0.99
    sphereNode.geometry!.firstMaterial!.roughness.contents = 0.01
    scene.rootNode.addChildNode(sphereNode)
    
    let sceneView = SCNView(frame: NSRect(x: 0, y: 0, width: 512, height: 512))
    sceneView.scene = scene
    
    // Setup pointOfView for the scene view:
    let cameraNode = SCNNode()
    cameraNode.camera = SCNCamera()
    cameraNode.camera!.wantsHDR = true
    cameraNode.camera!.wantsExposureAdaptation = false
    // Position camera ar +2 Z (it's looking forward towards -Z by default):
    cameraNode.simdPosition = float3(0, 0, 2)
    sceneView.pointOfView = cameraNode
    
    // Save a snapshot of the scene to ~/Desktop/test.png
    let img = sceneView.snapshot()
    let bmRep = NSBitmapImageRep(data: img.tiffRepresentation!)!
    let pngData = bmRep.representation(using: .png, properties: [:])!
    let url = FileManager.default.urls(for: .desktopDirectory,
                                       in: .userDomainMask).first!
        .appendingPathComponent("test.png")
    try! pngData.write(to: url, options: .atomic)
    print("Done")
}
renderTestSceneToDesktop()

The image it produces will show a mirror sphere surrounded by the "walls" of the cube map from the documentation page, and the camera looks (as it does by default) towards -Z. But note that -Z (from the background behind the camera) is reflected in the sphere, and the background behind the sphere has +Z on it, in the -Z direction.


So, is this a documentation or implementation bug?

Replies

AFAICS it is not possible to include images in this forum (!?) but here is a link to the image produced by the above program (that will have to wait for moderation, sigh).


(Note that the camera is positioned at Z=2 and looking (in the default direction) towards -Z, so the + and - signs are flipped in the texture.)