Jed Soane Jed Soane - 5 months ago 107
iOS Question

Textures not displaying correctly when using GoogleVR and SceneKit

I am experimenting with the Google-VR iOS SDK. I have a very simple SceneKit scene containing a single textured object. This is rendered in the GVRCardboardViewDelegate drawEye method using an SCNRenderer. When vrModeEnabled is set to false on the GVRCardboardView then the object renders correctly but when set to true the texture is not applied correctly. See the image below.

After more investigation I've found that loading a scene containing a textured object from SceneKit .scn file works fine. The problem occurs when loading an OBJ file (and it's .mtl file and jpg texture) into an SCNNode by using ModelIO like this:

let stageURL = NSBundle.mainBundle().URLForResource("newStage", withExtension: "obj", subdirectory: "Art.scnassets")
let stageAsset = MDLAsset(URL: stageURL)
let stageObject = asset.objectAtIndex(0)
let stage = SCNNode(MDLObject: stageObject)
scene.addChildNode(stage)


It seems like it might be an OpenGL state problem (and possibly a bug in ModelIO) but I haven’t been able to find a solution or workaround. Any suggestions?

Example of texture appearance. Top vrModeEnabled = false, bottom vrModeEnabled = true

Answer

Loading an OBJ file using ModelIO will implicitly use the associated material description file (which has the same file name as the OBJ file but with the extension .mtl) to provide textures and material properties for the geometry. Removing the material file and loading the texture explicitly fixed the problem.

let stageURL = NSBundle.mainBundle().URLForResource("newStage", withExtension: "obj", subdirectory: "Art.scnassets")
let stageAsset = MDLAsset(URL: stageURL)
let stageObject = asset.objectAtIndex(0)
let stage = SCNNode(MDLObject: stageObject)

let texture = SCNMaterial()
texture.diffuse.contents = UIImage(named: "Art.scnassets/stage.jpg")
stage.geometry?.firstMaterial = texture

scene.addChildNode(stage)

This is not an ideal solution but is an adequate workaround until I have time to debug the precise cause.

Note that prior to arriving at this solution I tried updating the texture properties in the SCNMaterialProperty on the node's diffuse material but this had no effect.

Comments