0

我正在尝试使用 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 中的一个错误),但我一直无法找到解决方案或解决方法。有什么建议么?

纹理外观示例。顶部 vrModeEnabled = 假,底部 vrModeEnabled = 真

纹理外观示例。 顶部 vrModeEnabled = 假,底部 vrModeEnabled = 真

4

1 回答 1

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 中的纹理属性,但这没有效果。

于 2016-06-07T22:04:25.737 回答