It is a kind of weird phenomena that I found out. There is a very simple example, I have an ARSCNView
which is empty, just rootnode and camera, so it means that the camera is open, but there is nothing on the screen (just camera).
There is a method that I call from the viewDidLoad() { printAllScene(node: scnView.scene.rootNode) }
in order to print all the nodes on the scene
private func printAllScene(node: SCNNode) {
print("node: \(node), parent is: \(String(describing: node.parent))")
for curNode in node.childNodes {
printAllScene(node: curNode)
}
}
This recursive method prints all the nodes on the scene, so after I call it in the viewDidLoad()
I get such an output
>>> 1
node: <SCNNode: 0x283313300 | 1 child>, parent is: nil
node: <SCNNode: 0x283318500 | camera=<SCNCamera: 0x1065261c0> | no child>, parent is: Optional(<SCNNode: 0x283313300 | 1 child>)
<<<
everything is ok here, but then after I call the same print method from the button click in a few seconds I get another output
>>> 3
node: <SCNNode: 0x283313300 | 3 children>, parent is: nil
node: <SCNNode: 0x283318500 pos(-0.002828 0.016848 0.034329) rot(0.229921 0.895326 -0.381477 0.336716) scale(1.000000 1.000000 1.000000) | camera=<SCNCamera: 0x1065261c0> | no child>, parent is: Optional(<SCNNode: 0x283313300 | 3 children>)
node: <SCNNode: 0x283336d00 | light=<SCNLight: 0x103973dd0 | type=probe> | no child>, parent is: Optional(<SCNNode: 0x283313300 | 3 children>)
node: <SCNNode: 0x283324800 pos(-0.007079 -0.074922 0.031407) rot(0.000000 -1.000000 0.000000 1.474911) | light=<SCNLight: 0x103985120 | type=probe> | no child>, parent is: Optional(<SCNNode: 0x283313300 | 3 children>)
<<<
It has already had 3 children instead of one, how?? and then after a few seconds more I try to click again and get another output
>>> 3
node: <SCNNode: 0x283313300 | 4 children>, parent is: nil
node: <SCNNode: 0x283318500 pos(0.000974 0.011970 0.039510) rot(0.231398 0.878019 -0.418974 0.304382) scale(1.000000 1.000000 1.000000) | camera=<SCNCamera: 0x1065261c0> | no child>, parent is: Optional(<SCNNode: 0x283313300 | 4 children>)
node: <SCNNode: 0x283336d00 | light=<SCNLight: 0x103973dd0 | type=probe> | no child>, parent is: Optional(<SCNNode: 0x283313300 | 4 children>)
node: <SCNNode: 0x283324800 pos(-0.007079 -0.074922 0.031407) rot(0.000000 -1.000000 0.000000 1.474911) | light=<SCNLight: 0x11aceec70 | type=probe> | no child>, parent is: Optional(<SCNNode: 0x283313300 | 4 children>)
node: <SCNNode: 0x28332ac00 pos(-0.007079 -0.074922 0.031407) rot(0.000000 -1.000000 0.000000 1.474911) | light=<SCNLight: 0x11b908130 | type=probe> | no child>, parent is: Optional(<SCNNode: 0x283313300 | 4 children>)
<<<
It has 4 children, interesting huh?
Could it be related to the configuration? Like the ARKit tried to create the light nodes related to the real light ambiance in order to simulate it on the scene or something like this?
UPD
Thanks to @mnuages, really this property automaticallyUpdatesLighting
seems very close to being the right solution, I set it in viewDidLoad
like this scnView.automaticallyUpdatesLighting = false
, but it doesn't make difference in my case, I still see that light nodes are adding.
UPD2
My current implementation is -
...
override func viewWillAppear(_ animated: Bool) {
let config = ARWorldTrackingConfiguration()
config.environmentTexturing = .automatic
scnView.session.run(config)
}
override func viewDidLoad() {
super.viewDidLoad()
scnView.scene = SCNScene()
scnView.scene.lightingEnvironment.contents = .none
scnView.scene.background.contents = .none
scnView.automaticallyUpdatesLighting = false
scnView.delegate = self
scnView.showsStatistics = true
...
But the problem is still reproducable.
Eventually, the problem was in ar configuration
ARKit automatically adds light probes when environment texturing is enabled. You can disable this behavior by setting the environmentTexturing property's value in your configuration to .none.