SCNLight .castsShadow = true stops rendering for a few seconds

Our app enables users to load .scn and .usdz 3D models and some of them contain lights with shadows enabled. When a node with a light and shadows is loaded from the model scene file and added as a child to a node in another SCNView, rendering of the SCNView pauses for a few seconds.

The pause is inconsistent: sometimes it pauses for seconds, sometimes it's only a few milliseconds. If the user adds multiple lights to the scene, the pause can be as long as 12 seconds, which results in a very bad user experience (i.e., scene freezes for seconds showing previous render).

Does anyone have any idea what this problem is or how to work around it?

I've tried many, many settings of the SCNLight parameters, and nothing seems to change it much. The lights that are part of the original scene have shadows enabled and I've not seen a rendering delay when that scene is loaded.

The user-added models are "prepared" for the scene view via its the SCNView .prepare method before being added to the scene, but that doesn't seem to have any effect on the delay (.prepare helps non-light node performance though).

I've tried debugging it with Instruments and it appears that it may be compiling one or more shaders during the rendering delay. If it's doing that on the rendering thread, that might explain it, but then how do I solve it?


Replies

Are you preparing an array of nodes within the prepare method? If yes, try adding everything to the scene (nodes and lights) first and then pass the whole Scene into the prepare method. That might help, as ARKit can then also compile the required shaders.