Programmatically created SCNMaterial vs SceneKit Viewer

In the viewer, the model looks great. I then bring it into the scene and it looks great. But I want to change the material programmatically. Yet this makes it look ugly. It's a physically based light model and a metallic material. Yet renders like a relatively flat phong. The detail of the other maps is there. The color is just flat and off.

To eliminate all other variables, I started applying my programmatic material right after creating the node. The material is intended to be the exact same as the one I set in the viewer. Yet I get the same ugly result when I set it to the programmatically created version.

Then I only changed the diffuse contents. And this looks great. Hopefully this isn't a stupid question as I can't find any similar complaints. But what parameter is being set in the viewer that I am missing in the SCNMaterial?

The following is my attempt to copy all the settings from my viewer and repeat it in code. Nothing has really changed anything from just setting the usual content values:

        let material = SCNMaterial()
        material.lightingModel = .physicallyBased
        let matScale: Float = 1.0///25.4
        material.isDoubleSided = false
        material.diffuse.contents = UIImage(named: "basecolor.png")
        //material.diffuse.contentsTransform = SCNMatrix4MakeScale(matScale, matScale, matScale)
        material.diffuse.wrapS = .repeat
        material.diffuse.wrapT = .repeat
        material.diffuse.mipFilter = .nearest
        material.diffuse.magnificationFilter = .linear
        material.diffuse.minificationFilter = .linear
        material.diffuse.mappingChannel = 0
        material.diffuse.maxAnisotropy = 1.0
        material.metalness.contents = UIImage(named: "scuffed_metalic.png")
        material.metalness.wrapS = .repeat
        material.metalness.wrapT = .repeat
        material.metalness.mipFilter = .nearest
        material.metalness.magnificationFilter = .linear
        material.metalness.minificationFilter = .linear
        material.metalness.mappingChannel = 0
        material.metalness.maxAnisotropy = 1.0
        material.roughness.contents = UIImage(named: "scuffed_roughness.png")
        material.roughness.wrapS = .repeat
        material.roughness.wrapT = .repeat
        material.roughness.mipFilter = .nearest
        material.roughness.magnificationFilter = .linear
        material.roughness.minificationFilter = .linear
        material.roughness.mappingChannel = 0
        material.roughness.maxAnisotropy = 1.0
        material.normal.contents = UIImage(named: "scuffed_normal.png")
        material.normal.wrapS = .repeat
        material.normal.wrapT = .repeat
        material.normal.mipFilter = .nearest
        material.normal.magnificationFilter = .linear
        material.normal.minificationFilter = .linear
        material.normal.mappingChannel = 0
        material.normal.maxAnisotropy = 1.0
        material.metalness.intensity = 1.0
        material.roughness.intensity = 1.0//0.0//0.3
        material.normal.intensity = 1.0
        material.diffuse.intensity = 1.0
       material.multiply.contents = UIColor.white
        material.multiply.intensity = 1.0
        material.transparent.contents = UIColor.white
        material.transparent.intensity = 1.0
        material.clearCoatNormal.contents = UIColor.white
        material.clearCoatNormal.intensity = 1.0
        material.locksAmbientWithDiffuse = true
        material.emission.contents = UIColor.black
        material.emission.intensity = 1.0
        material.selfIllumination.contents = UIColor.black
        material.selfIllumination.intensity = 1.0
        material.clearCoatRoughness.contents = UIColor.black
        material.clearCoatRoughness.intensity = 1.0
        material.displacement.contents = UIColor.black
        material.displacement.intensity = 1.0
        material.transparencyMode = .default
        material.shininess = 1.0
        material.fresnelExponent = 0.0
        material.cullMode = .back
        material.blendMode = .alpha
        material.writesToDepthBuffer = true
        material.readsFromDepthBuffer = true
        material.locksAmbientWithDiffuse = true
        material.isLitPerPixel = true
  • Oof. All that debugging and it was a misspelling of "metallic" on the metalness contents file. Well, I got some refactoring out of it.

Add a Comment

Accepted Reply

Hmm, it's hard to say based off of the info provided here. It would be better to have a full, focused example project that demonstrates the issue. I recommend that you request technical support for this issue, as that will provide a better format to getting the info needed to answer this question.

Replies

Hmm, it's hard to say based off of the info provided here. It would be better to have a full, focused example project that demonstrates the issue. I recommend that you request technical support for this issue, as that will provide a better format to getting the info needed to answer this question.

Thank you for the reply. I'm not too familiar with how this forum works despite how long I've been a member. I had tried to add a comment yesterday to explain what I found but I don't see it anywhere. So that doesn't work how I thought it did. But my problem was due to a simple misspelling when setting the metallic contents. I just had it in my brain as being similar to another issue related to trying to match colors and so I didn't see the simple answer first. The viewer was using the file being dropped directly into the spot. So no spelling issues there. And yet the programmatic equivalent was effectively being set to nil. It is all working now. Thanks.

Ah ok great, I'm glad you were able to identify the issue!