本文介绍了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.这是完成该任务的两种略有不同的方法.

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-19 03:23