本文介绍了ios - 如何将 mtl 纹理文件应用于 OBJ的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用 ModelI/O 来展示 3D 模型.这是我的代码:

I'm working with ModelI/O to show 3D model. This is my code:

// Load the .OBJ file
    guard let url = Bundle.main.url(forResource: "agera r", withExtension: "obj") else {
        fatalError("Failed to find model file.")
    }

    let asset = MDLAsset(url:url)
    guard let object = asset.object(at: 0) as? MDLMesh else {
        fatalError("Failed to get mesh from asset.")
    }

    // Create a material from the various textures
    let scatteringFunction = MDLScatteringFunction()
    let material = MDLMaterial(name: "baseMaterial", scatteringFunction: scatteringFunction)
    let textureFileName = "agera_r.mtl"
    material.setTextureProperties([.baseColor: textureFileName])

    // Apply the texture to every submesh of the asset
    for submesh in object.submeshes!  {
        if let submesh = submesh 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.autoenablesDefaultLighting = true
    sceneView.allowsCameraControl = true
    sceneView.scene = scene
    sceneView.backgroundColor = UIColor.black
}
extension MDLMaterial {
func setTextureProperties(_ textures: [MDLMaterialSemantic:String]) -> Void {
    for (key,value) in textures {
        guard let url = Bundle.main.url(forResource: value, withExtension: "") else {
            fatalError("Failed to find URL for resource (value).")
        }
        let property = MDLMaterialProperty(name:value, semantic: key, url: url)
        self.setProperty(property)
    }
}

问题是当应用程序运行时,显示了 3D 模型,但 .mtl 纹理文件不适用于它.如何解决这个问题?谢谢大家.

The problem is when the app run, the 3D model is shown but the .mtl texture file not apply to it. How to fix this issue? Thanks all.

推荐答案

这行的主要问题:

let textureFileName = "agera_r.mtl"
material.setTextureProperties([.baseColor: textureFileName])

您应该将 URL 传递给纹理文件而不是 .mtl 文件 URL.这段代码对我来说很好用:

You should pass URL to the texture file instead of .mtl file URL.This code works fine for me:

目标-C

MDLScatteringFunction *scatFunction = [MDLScatteringFunction new];
MDLMaterial *mdlMaterial = [[MDLMaterial alloc] initWithName:@"material" scatteringFunction:scatFunction];
MDLMaterialProperty *bcProperty = [[MDLMaterialProperty alloc] initWithName:@"BaseColor" semantic:MDLMaterialSemanticBaseColor URL:textureFileURL];
[mdlMaterial setProperty:bcProperty];
SCNMaterial *material = [SCNMaterial materialWithMDLMaterial:mdlMaterial];
node.geometry.firstMaterial = material;

SWIFT

let scatFunction = MDLScatteringFunction()
let material = MDLMaterial(name: "material", scatteringFunction: scatFunction)
material.setTextureProperties(textures: [.baseColor: "model/texture.png"])
mesh.submeshes?.forEach {
    if let submesh = $0 as? MDLSubmesh {
        submesh.material = material
    }
}

baseNode = SCNNode(mdlObject: mesh)

附言这是完成该任务的两种略有不同的方法.

P.S. This is two slightly different approaches to that task.

更新:

let baseNode = SCNScene(named: "mesh.obj")!.rootNode

您也可以尝试使用这种方法.如果我没记错的话,它会连接 .mtl 文件和其他纹理.(如果.obj文件的.mtl文件路径有效,.mtl文件的纹理路径也有效)

Also you can try to use this approach. If I recall correctly it will hook up .mtl file and other textures. (If path to .mtl file, which written in .obj file, is valid and paths to the textures in .mtl also valid)

这篇关于ios - 如何将 mtl 纹理文件应用于 OBJ的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

09-09 08:48