4

I am trying to use the new iOS13 ability to export a usdz file from a SCNScene using the func write(to url: URL, options: [String : Any]? = nil, delegate: SCNSceneExportDelegate?, progressHandler: SCNSceneExportProgressHandler? = nil) -> Bool function of SCNScene.

If I use a baked in .scn file with no modifications, it works great but I run into all sorts of problems when I try to insert in my own texture.

let scene = SCNScene(named: "scene.scnassets/original.scn")!
let node = scene.rootNode.childNode(withName: "Plane", recursively: true)
let plane = SCNPlane(width: 1, height: 1)
node?.geometry = plane
node?.geometry?.firstMaterial?.diffuse.contents = UIColor.black
node?.geometry?.firstMaterial?.roughness.contents = NSNumber(value: 0.0) //or UIColor.black doesn't work either

let documentsUrl = self.fileManager.urls(for: .documentDirectory, in: .userDomainMask)
guard !documentsUrl.isEmpty,
let url = documentsUrl.first else {
    completion(nil)
    return
}
let finalUrl = url.appendingPathComponent("result.usdz")
_ = scene.write(to: finalUrl, delegate: nil)

original.scn just has a glossy plane and I've tried to again set the roughness to 0 when I change the material. The resulting usdz always has the roughness set to 0.9 though. Has anyone else experienced this and found a way around it?

geraldk
  • 43
  • 4

1 Answers1

4

The default lighting model is SCNLightingModelBlinn which means the material used for the plane geometry is not physically based. USDZ only supports physically based materials and upon export SceneKit will try to build a PBR material from the Blinn material, and will infer a roughness on your behalf.

The fix consists in setting lightingModelName to SCNLightingModelPhysicallyBased.

mnuages
  • 13,049
  • 2
  • 23
  • 40
  • That did it, thanks! I just needed to add the following line `node.geometry?.firstMaterial?.lightingModel = .physicallyBased` – geraldk Apr 28 '20 at 07:24