9

设计师已经交付了三个文件:

  • 图片。jpg
  • 某物。mtl
  • 任何。对象

我可以像这样成功地将 .obj 文件加载到我的场景中:

  SCNView * sceneView = [SCNView new];
  sceneView.frame = view.bounds;
  [view addSubview:sceneView];

  SCNScene * scene = [SCNScene sceneNamed:@"models.scnassets/whatever.obj"];
  [sceneView setScene:scene];

我正在努力将 .jpg 和 .mtl 文件应用于 .obj 文件。我尝试使用以下代码应用图像,但不喜欢:

SCNMaterial * material = [SCNMaterial material];
material.diffuse.contents = [UIImage imageNamed:@"image.jpg"];

SCNNode * materialNode = [SCNNode node];
materialNode.geometry.firstMaterial = material;
[scene.rootNode addChildNode:materialNode];
4

3 回答 3

4

嗨@Johnny 有多种方法可以在 .obj 文件上应用纹理文件。

  1. 如果您想加载一些具有出色自定义功能的 .obj 文件,您可以在 Xcode 中打开 .obj 文件并应用纹理(漫反射贴图、法线贴图等、环境和灯光相机),然后 .obj 文件将转换 .scn 文件以在 SCNView 中使用.

  2. 如果您想在 .obj 或 .scn 文件的特定节点上动态应用纹理/更改纹理,您可以使用模型 I/O 框架,它使用集成了 MetalKit、GLKit 和 SceneKit 的通用基础架构提供导入、导出和操作 3D 模型. SceneKit 为 ModelIO 资产 ex..+ (instancetype)sceneWithMDLAsset:(MDLAsset *)mdlAsset;(正如@Zeeshan 回答的那样) 提供类。

  3. 您的设计师可能会以 .dae 格式导出 3D 模型文件。在 .dae 文件中,单个文件包含纹理、相机、灯光参考。在 .obj 中使用时不需要 .mtl 或其他文件。SCNKit 也支持 .dae

  4. 如果你使用金属渲染,你可以直接从 NSURL 加载纹理。

于 2017-10-09T06:34:27.123 回答
2

尽管没有使用 .mtl 文件,但这让我有了一些了解:

//START 3D
    NSURL * url = [[NSBundle mainBundle] URLForResource:@"playerModel" withExtension:@"obj"];
    MDLAsset * asset = [[MDLAsset alloc] initWithURL:url];
    MDLMesh * object = (MDLMesh *)[asset objectAtIndex:0];

    MDLScatteringFunction * scatFunction = [MDLScatteringFunction new];
    MDLMaterial * material = [[MDLMaterial alloc] initWithName:@"playerMaterial" scatteringFunction:scatFunction];

    NSURL * materialURL = [[NSBundle mainBundle] URLForResource:skinFilename withExtension:@"jpg"];
    MDLMaterialProperty * baseColour = [MDLMaterialProperty new];
    [baseColour setType:MDLMaterialPropertyTypeTexture];
    [baseColour setSemantic:MDLMaterialSemanticBaseColor];
    [baseColour setURLValue:materialURL];
    [material setProperty:baseColour];

    for (MDLSubmesh * sub in object.submeshes){
        sub.material = material;
    }

    SCNScene * scene = [SCNScene new];
    SCNNode * node = [SCNNode nodeWithMDLObject:object];
    SCNVector3 v = SCNVector3Make(100, 200, 0);
    [node setPosition:v];
    [scene.rootNode addChildNode:node];

    SCNView * view = [SCNView new];
    view.frame = transferInView.bounds;
    view.autoenablesDefaultLighting = true;
    view.allowsCameraControl = false;
    view.scene = scene;
    view.backgroundColor = [UIColor clearColor];
    [transferInView addSubview:view];

    SCNAction * rotate = [SCNAction rotateByX:0 y:1 z:0 duration:1.0f];
    [node runAction:[SCNAction repeatActionForever:rotate]];

    SCNVector3 min = SCNVector3Zero;
    SCNVector3 max = SCNVector3Zero;
    [node getBoundingBoxMin:&min max:&max];
    node.pivot = SCNMatrix4MakeTranslation((max.x - min.x) / 2 + min.x, (max.y - min.y) / 2 + min.y, 0);

    //END 3D
于 2017-10-25T20:31:09.123 回答
0

我遇到了同样的问题,我找到的唯一解决方案是在这个链接点击这里。我可以加载 .mtl 信息是通过场景创建对象

let scene = SCNScene(named: "rose.obj")

确保在您的包中包含带有纹理的 .mtl 和 jpg。

于 2017-10-06T10:02:22.623 回答