0

I want to create a 3D scene with the SceneKit modeler and then read it into my Metal app. I see there is SceneKit and ModelIO API to do this but I am unclear on how the pieces fit together.

So, what I need is path from .scn file -> MDL Mesh -> geometry + texture. I am unclear on how I would sync my Metal shaders with materials created in the SceneKit modeler.

dugla
  • 12,774
  • 26
  • 88
  • 136

1 Answers1

6

There's two main parts to what you're asking here: getting SceneKit data into ModelIO, and rendering ModelIO data with Metal.

  1. To get SceneKit scenes into ModelIO, first use SceneKit API (SCNScene or SCNSceneSource to load the .scn file, then use ModelIO API to get the objects you want as meshes. You can create a MDLAsset from the entire scene using assetWithSCNScene:bufferAllocator: and then walk through the asset's object hierarchy in ModelIO to find the mesh you want, or walk through the node hierarchy in SceneKit to find the SCNNode or SCNGeometry you want and then get the mesh to ModelIO using objectWithSCNNode:bufferAllocator: or meshWithSCNGeometry:bufferAllocator:.

  2. As for using ModelIO meshes in a Metal app, Apple has a sample code project that shows how to use ModelIO to load an OBJ mesh, use MetalKit to get the mesh data into Metal GPU buffers, and hook up the material information you get from ModelIO to shader variables for use in your own renderer.

You should be able to put the two of these together: where the sample code loads an OBJ to get a MDLAsset or MDLMesh, use the methods in (1) to get an asset or mesh out of a SceneKit file instead.

The SceneKit material model is of course much more complicated than the simple Phong shader used in the sample code. But the sample code does show how to iterate through a MDLMaterial's properties and set corresponding arguments in a Metal shader — if you create a more complicated shader, just follow the same steps to map the material properties to whatever your shader's inputs are.

rickster
  • 124,678
  • 26
  • 272
  • 326
  • Ah hah! So - in a nutshell - I give geometry and materials names in the modeler: "my box", "cool material" and then retrieve the geometry/material during the traversal - via either SceneKit or ModelIO traversal methods. The key is to label things. Have I got that right? – dugla Nov 03 '16 at 20:15
  • You can iterate materials regardless of whether they're labeled, but labels certainly can help you keep track. – rickster Nov 03 '16 at 21:03
  • Wait, what? How do I identify an item in the scene without a label. Two textured spheres implies four (4) labels (assuming distinct material descriptions) no? – dugla Nov 03 '16 at 21:11
  • Although assetWithSCNScene:bufferAllocator: is documented - https://developer.apple.com/reference/modelio/mdlasset?language=objc - it is not actually available to use. Typing in the method call in code shows the method is not available. Sigh ... – dugla Nov 04 '16 at 10:49
  • 3
    You need to `import SceneKit.ModelIO` or `#import ` to get the SCN/MDL bridging bits. – rickster Nov 04 '16 at 15:15