I need to make a transparent object in SceneKit that casts a shadow. I tried going through all the texture settings, but I didn't get a positive result. If you completely hide the textures of the object, the shadow disappears.
I need to get a shadow without displaying an object and I don't understand how to do it.
To make an invisible object that casts a shadow in SceneKit, use .shadowOnly
lighting model.
import SceneKit
import Cocoa
class ViewController: NSViewController {
override func viewDidLoad() {
super.viewDidLoad()
let sceneView = self.view as! SCNView
sceneView.scene = SCNScene()
sceneView.backgroundColor = .darkGray
sceneView.allowsCameraControl = true
let lightNode = SCNNode()
lightNode.light = SCNLight()
lightNode.light?.type = .directional
lightNode.light?.castsShadow = true
lightNode.eulerAngles.x = -.pi/4
sceneView.scene?.rootNode.addChildNode(lightNode)
let sphere = SCNNode(geometry: SCNSphere(radius: 2))
sphere.geometry?.firstMaterial?.lightingModel = .shadowOnly // 1
sphere.geometry?.firstMaterial?.colorBufferWriteMask = [] // 2
sphere.geometry?.firstMaterial?.transparencyMode = .rgbZero // 3
sceneView.scene?.rootNode.addChildNode(sphere)
let plane = SCNNode(geometry: SCNPlane(width: 10, height: 10))
plane.position.y = -2
plane.eulerAngles.x = -.pi/2
sceneView.scene?.rootNode.addChildNode(plane)
}
}
If you need just a shadow catcher (i.e. transparent plane) add the following line to your code:
plane.geometry?.firstMaterial?.lightingModel = .shadowOnly
To control shadow's transparency use this property:
lightNode.light?.shadowColor = NSColor(white: 0, alpha: 0.5)