使用GoogleVR和SceneKit时纹理无法正确显示

时间:2016-06-03 02:54:27

标签: ios opengl-es scenekit google-vr

我正在尝试使用Google-VR iOS SDK。我有一个非常简单的SceneKit场景,包含一个纹理对象。这是使用SCNRenderer在GVRCardboardViewDelegate drawEye方法中呈现的。当在GVRCardboardView上将vrModeEnabled设置为false时,该对象将正确呈现,但是当设置为true时,纹理未正确应用。见下图。

经过更多调查后,我发现在SceneKit .scn文件中加载包含纹理对象的场景可以正常工作。使用ModelIO将OBJ文件(及其.mtl文件和jpg纹理)加载到SCNNode时会出现问题:

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)

好像它可能是一个OpenGL状态问题(可能是ModelIO中的一个错误),但我找不到解决方案或解决方法。有什么建议吗?

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

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

1 个答案:

答案 0 :(得分:2)

更新:实际解决方案很简单。由于某种未知的原因,纹理变换被搞砸了。将以下行添加到问题中的代码中会使纹理按预期显示。

var transformForTexture = SCNMatrix4MakeScale(1, -1, 1);
transformForTexture = SCNMatrix4Translate(transformForTexture, 0, 1, 0)
stage.geometry?.firstMaterial?.diffuse.contentsTransform = transformForTexture

原始解决方法:

使用ModelIO加载OBJ文件将隐式使用关联的材质描述文件(其文件名与OBJ文件相同,但扩展名为.mtl),以提供几何体的纹理和材质属性。删除材质文件并加载纹理明确解决了问题。

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)

这不是一个理想的解决方案,但在我有时间调试确切原因之前,这是一个充分的解决方法。

请注意,在到达此解决方案之前,我尝试在节点的漫反射材质上更新SCNMaterialProperty中的纹理属性,但这没有效果。