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.
There's two main parts to what you're asking here: getting SceneKit data into ModelIO, and rendering ModelIO data with Metal.
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:
.
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.