【发布时间】:2021-12-09 06:22:09
【问题描述】:
在我的 3d obj 模型上应用特定纹理时,我现在有点卡住了。
最简单的解决方案是使用let test = SCNScene(named: "models.scnassets/modelFolder/ModelName.obj"),但这需要 mtl 文件将纹理文件直接映射到其中,这在我当前的工作流程中是不可能的。
根据我目前的理解,这让我可以选择使用散射函数将纹理应用于特定语义,例如:
if let url = URL(string: obj) {
let asset = MDLAsset(url: url)
guard let object = asset.object(at: 0) as? MDLMesh else {
print("Failed to get mesh from asset.")
self.presentAlert(title: "Warning", message: "Could not fetch the model.", firstBtn: "Ok")
return
}
// Create a material from the various textures with a scatteringFunction
let scatteringFunction = MDLScatteringFunction()
let material = MDLMaterial(name: "material", scatteringFunction: scatteringFunction)
let property = MDLMaterialProperty(name: "texture", semantic: .baseColor, url: URL(string: self.textureURL))
material.setProperty(property)
// Apply the texture to every submesh of the asset
object.submeshes?.forEach {
if let submesh = $0 as? MDLSubmesh {
submesh.material = material
}
}
// Wrap the ModelIO object in a SceneKit object
let node = SCNNode(mdlObject: object)
let scene = SCNScene()
scene.rootNode.addChildNode(node)
// Set up the SceneView
sceneView.scene = scene
...
}
实际的问题是语义。 3d 模型是在 Unreal 上制作的,对于许多模型来说,有一个 png 纹理,其中包含 3 种语义,即环境光遮蔽、粗糙度和金属。需要在红色通道上应用环境光遮蔽,在贪婪通道上应用粗糙度,在蓝色通道上应用金属。
我怎样才能做到这一点? MdlMaterialSemantic 具有所有these 可能的语义,但金属、环境光遮蔽和粗糙度都是分开的。我尝试简单地在每个上应用纹理,但显然效果不佳。
考虑到我的 .png 纹理将所有这 3 个“打包”在不同的通道下,我该如何处理?我在想也许我可以以某种方式使用一个小脚本直接在应用程序中将映射添加到我端的 mtl 文件中的纹理,但这似乎很粗略哈哈..
如果无法做到这一点,我还有哪些其他选择?我也一直在尝试将 fbx 文件与 assimpKit 一起使用,但我无法加载任何纹理,只能加载黑色模型......
我愿意接受任何建议,如果需要更多信息,请告诉我!非常感谢!
【问题讨论】:
标签: swift scenekit texture-mapping 3d-model