Why are my shadows pixelated/choppy in SceneKit?

Viewed 297

I am having trouble getting smooth shadows in SceneKit. Below you will find the code which adds both lights to my scene, as well as a picture. I circled the areas which are pixelated.

Even the basic geometries provided by SceneKit are not being shaded correctly.

Does anyone know how I can fix this?

Thank you!

        let directionalLight = SCNNode()
        directionalLight.light = SCNLight()
        directionalLight.light?.type = .directional
        directionalLight.light?.castsShadow = true
        directionalLight.eulerAngles = SCNVector3(0, -toRadians(angle: 45), -toRadians(angle: 60))
        self.scene.rootNode.addChildNode(directionalLight)
        let ambientLight = SCNNode()
        ambientLight.light = SCNLight()
        ambientLight.light?.type = .ambient
        ambientLight.light?.color = UIColor.darkGray
        ambientLight.light?.intensity = 5000
        self.scene.rootNode.addChildNode(ambientLight)

See Picture

1 Answers

SceneKit uses a technique called "shadow mapping" to render shadows. These effects are normal to this technique but are a bit extreme in your case.

Lots of information on shadow mapping and how to get the best result out of it is available and worth a Google query if you want to know more

In your case i think the first to look at is the position of your directionalLight node and the shadowMapSize of it's SCNLight.

Why the position of a directional light? SceneKit will render a depth only image of your scene from the lights perspective and then use this image to calculate if pixels on your final render are in shadow. If the light position is far away from your scene then the scene will only take up a small part of this shadow map.

Another way to make sure your scene has a lot of usable pixels on the shadow map is by simply increasing the shadow map size using the shadowMapSize property. This will increase render time and GPU memory usage tough, so try to find a "sweet-spot" here.

Related