'SceneKit – Why does adding spot light blacken the floor?

Screenshot #1 shows a simple SceneKit scene with only an ambient light (explicitly added, not the default one).

Screenshot #2 shows what happens after adding a spot light. The whole floor turns black. This spot light has the default properties after adding a spot light within the SceneKit Editor.

This also happens with a directional light.

To be clear, it is understood that the scene contains ambient lighting by default. However, we explicitly added an ambient light (and even tested with two) before adding the spot/directional light. So the default light theory mentioned in this question no longer apply. Hence the confusion.

Spot lights and directional lights are supposed to add light to a particular region of the scene, that is understood. But they shouldn't blacken areas outside their scope, right?

New to 3D graphics and SceneKit so any advice is very much appreciated.

Screenshot #1: enter image description here

Screenshot #2: enter image description here



Solution 1:[1]

What's the issue

An empty SceneKit's scene (without any added light) has a default omnidirectional light that you can easily turn on or off:

sceneView.autoenablesDefaultLighting = true

Let's see what Apple documentation says about it:

If this property’s value is false (the default), the only light sources SceneKit uses for rendering a scene are those contained in the scene graph. If you change the value to true, SceneKit automatically adds and places an omnidirectional light source when rendering scenes that contain no lights or only contain ambient lights.

When you add lights to your scene they behave correspondingly. The main principles are:

  • If a new light is added, default SceneKit's light turns off.

  • If light's rays are parallel to any 3D surface that surface will be black.

    • This behavior is true for Directional Light or Spot Light with a narrow light-cone.
    • That occurs because SceneKit has no Global Illumination option (or secondary light rays).
  • Ambient light is omnidirectional and has NO decay. It has only shading for surface normals.

  • Point light is omnidirectional and has a decay (light loses its intensity depending on distance).

That's why floor in your scene turned black.

And remember – you can easily turn any light on or off:

@IBAction func turnLight(_ sender: NSButton) {   

    if counter % 2 == 0 {
        ambientLightNode.isHidden = true
    } else {
        ambientLightNode.isHidden = false
    }
    counter += 1
}

Solution

When you're lighting your scene you need to use several light types. If you use just Directional Light, some objects' surfaces in your scene will be black, so use additional Ambient Light with low intensity – 200 to 500 lumens – to lighten these black surfaces. Don't use too many Point Lights, because each Point Light is a set of 6 Spot Lights with 90 degree cones. So each Point Light with turned on shadows is computationally intensive!

P.S.

If you're interested in RealityKit lighting, read my story on Medium.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1