How does SceneKit preload assets?

Hi,


I'm trying to understand what SceneKit does to load assets — when it loads them, where it loads them, etc..


I cannot find detailed documentation on this but maybe I'm looking in the wrong place. The best I've found so far

is the discussion sections in the API docs for SCNSceneRenderer.prepare(_:withCompletionHandler: ) and SCNSceneRenderer.prepare(_:shouldAbortBlock: ).


Both of these methods have discussion sections that say the following:

By default, SceneKit lazily loads resources onto the GPU for rendering. This approach uses memory and GPU bandwidth efficiently, but can lead to stutters in an otherwise smooth frame rate when you add large amounts of new content to an animated scene. To avoid such issues, use this method to prepare content for drawing before adding it to the scene. You can call this method on a secondary thread to prepare content asynchronously.


SceneKit prepares all content associated with the

object
parameter you provide. If you provide an
SCNMaterial
object, SceneKit loads any texture images assigned to its material properties. If you provide an
SCNGeometry
object, SceneKit loads all materials attached to the geometry, as well as its vertex data. If you provide an
SCNNode
or
SCNScene
object, SceneKit loads all geometries and materials associated with the node and all its child nodes, or with the entire node hierarchy of the scene.

...

You can observe the progress of this operation with the

Progress
class. For details, see
Progress
.


This raises more questions for me, some of them probably pretty basic (I'm no expert in 3D graphics programming), and some maybe not so dumb:


  1. Does "loads resources onto the GPU" mean it is loading the assets into dedicated memroy separate from normal RAM? Or into normal RAM reserved for the GPU? Or into some kind of memory that's actually on the GPU? (This is the dumb question, I bet.)
  2. How many assets can be loaded ahead of time in this way?
  3. What happens if I try to load more than can fit?
  4. If SceneKit uses "a secondary thread to prepare content asynchronously", what happens if I try to access the content before the background loading operation completes? Does my access block or fail?
  5. If I can observe the operation with an NSProgress object, then how come these methods do not return NSProgress instances? Or how come the SCNSceneRenderer does not provide an accessor to get return an NSProgress instance?

I'd appreciate any insight into these questions, or pointers to WWDC videos, documentation, or third-party books that go into enough detail that they would address these questions.

Thanks!

  • Good evening, I have a question related to your post : https://developer.apple.com/forums/thread/699227

    Is there any tutorial on how to use the prepareObject:shouldAbortBlock: and the prepareObjects:withCompletionHandler methods?

    In our case the SceneView is an ARCNView, so we can't seem to access the SCNSceneRenderer methods. We have only managed to implement the "Prepare" method to preload our assets : https://developer.apple.com/documentation/scenekit/scnscenerenderer/1523375-prepare

    It seems to be doing something because we get a significantly longer freeze at the start of the experience, however we still experience the same fps drops during the experience when our objects appear for the first time.

Add a Comment

Replies

Have a look at my post onSceneKit and On Demand Resources.

Hmm,


This is interesting but seems to address a different and earlier stage of pre-loading: the placing of a SceneKit asset into the application bundle, as opposed to lazily downloading it from the network as an On-Demand Resource.


So to summarize, there's at least three kinds loading one could describe as pre-loading of SceneKit resources:


1. On-Demand Resources. "Preloading" .scn files by installing them in the bundle, so they are not lazily downloaded from the App Store asset servers


2. Early object instantiation. Initializing SCNScene objects from a file-based URL early, before they are needed, so that one doesn't pay the cost of reading the .scn file from disk into memory and initializing an SCNScene object (for instance) at a point when the delay would be noticeable.


3. Early loading of objects "into the GPU". Calling the SCNSceneRenderer.prepare(_:withCompletionHandler: ) method I mentioned in the original post, which takes a fully-initialized SCNScene as its argument, and "loads it into the GPU" eagerly. If you don't call this, then SceneKit does this lazily, that is, at last possible moment.


My questions is about mechanism 3, and the meaning and limits of loading the SceneKit assets into the GPU.

I think you should send an e-mail to the guys who do the SceneKit WWDC sessions.