6

Based on the advice in this answer, the goal is to add an ambient light to a scene along with a directional light to the camera.

This works in the Xcode Scene Editor, with the directional light set at 70% white and the ambient light at 50% white. The Euler angles for the directional light use default values.

Coding this arrangement fails. It's as if the directional light isn't being added. There is no effect on the scene; it's as if only the ambient light exists.

Different values for the x component of the Euler angles make no difference -- PI/2, PI, and other values were tried but still no change.

Adding the directional light to the scene's root node (scene.rootNode.addChildNode(directionalLightNode)), however, does indeed add the light to the scene.

fileprivate func addLightNode() {
    // Create ambient light
    let ambientLightNode = SCNNode()
    ambientLightNode.light = SCNLight()
    ambientLightNode.light!.type = .ambient
    ambientLightNode.light!.color = UIColor(white: 0.70, alpha: 1.0)

    // Add ambient light to scene
    scene.rootNode.addChildNode(ambientLightNode)

    // Create directional light
    let directionalLight = SCNNode()
    directionalLight.light = SCNLight()
    directionalLight.light!.type = .directional
    directionalLight.light!.color = UIColor(white: 1.0, alpha: 1.0)
    directionalLight.eulerAngles = SCNVector3(x: 0, y: 0, z: 0)

    // Add directional light to camera
    let cameraNode = sceneView.pointOfView!
    cameraNode.addChildNode(directionalLight)
}
Crashalot
  • 33,605
  • 61
  • 269
  • 439

1 Answers1

4

Create a SCNNode with for example the name cameraNode. Create a SCNCamera and assign it to the camera property of cameraNode. Add the cameraNode to the scene (as a child of the rootNode).

After that you can add the light node as a child node of cameraNode or, given it’s the only camera, as a child of the pointOfView node (which now represents the cameraNode you created and added to the scene). The default camera and its pointOfView node are not part of the scene’s object hierarchy.

Xartec
  • 2,369
  • 11
  • 22
  • yup, this is what we realized after posting the bounty. we were going to post the answer, but yours will do and you can earn extra points. :) – Crashalot Feb 28 '18 at 00:28
  • do you happen to know how the default camera implements zoom functionality? one answer from 2015 claims the Fov values change when pinching, but that doesn't appear to be the case now. The Fov values remain the same no matter how much you zoom. – Crashalot Feb 28 '18 at 01:06
  • It is indeed the fieldOfView value (scnView.pointOfView.camera.fieldOfView) that changes when using the default camera controls. – Xartec Feb 28 '18 at 01:33
  • you're right, it seems that saving the node associated with `pointOfView` does not work properly, hence the value wasn't changing, thanks! – Crashalot Feb 28 '18 at 01:56
  • how about when you pan? checking the `rotation` property of an imported OBJ node (`scene.rootNode.childNodes.first`), the values don't seem to change even when the model spins around. trying to implement that part of the default camera as well. do you know what the default camera is doing there? – Crashalot Feb 28 '18 at 02:29
  • 1
    It is not the model that spins around when using default camera controls. The camera rotates around the model merely giving that impression. See the rotation value of the pointOfView instead. An easy way to get a similar effect manually is to create a helper node, just an empty SCNNode, and place that at the center where you want to orbit around with the camera. Then place the cameraNode at a certain z value (whatever works for your scene/model size and fov) and make that camera a child node of the helper node and then rotate the helper node based on pan gesture input. – Xartec Feb 28 '18 at 04:24
  • See this answer from rickster for example: https://stackoverflow.com/questions/25654772/rotate-scncamera-node-looking-at-an-object-around-an-imaginary-sphere?noredirect=1&lq=1 – Xartec Feb 28 '18 at 04:26
  • Thanks so much! Any reason why doing the empty SCNNode is better than rotating the model itself? – Crashalot Feb 28 '18 at 08:02
  • It depends on what you want to do. If there is only one model, no background scene, the end result will be the same. – Xartec Mar 01 '18 at 01:31
  • OK, thanks. Just wanted to make sure some angle wasn't overlooked. – Crashalot Mar 01 '18 at 21:45