gpt4 book ai didi

swift - ModelIO 框架不工作

转载 作者:搜寻专家 更新时间:2023-10-31 19:30:24 24 4
gpt4 key购买 nike

我正在尝试导入 3D 模型文件并使用 Metal 渲染它们使用 ModelIOMetalKit (在 OS X 10.11 上),但我从这些框架中看到的行为(特别是 ModelIO )并不符合预期。

我可以导入 .obj文件并将它们转换为 MetalKit网格而不会导致任何错误,但网格(至少在渲染下)似乎只是一个三角形的大粉丝,所有三角形都从一个点发出。下面截图中的模型应该是“Suzanne”猴头的分割版: Incorrectly imported .obj file

在检查中,MDLSubmesh 的顶点索引从导入的文件没有任何意义。连续的索引集继续引用索引 0 处的顶点,有时在同一组索引中出现多次,这可以解释渲染过程中的外观。我已经确认这个 .obj文件可以很好地导入其他应用程序。

我试过导入其他 3D 文件格式(框架官方支持的所有格式),但除了 .obj 以外的任何格式导致未捕获 NSException正在调用 MDLAssetinit() .

我正在使用 Xcode 7.2 并以 OS X 10.11 为目标。

最佳答案

我也遇到过类似的问题,虽然我是 Metal 的菜鸟,但我想通了一些事情。

我试图导入 Melita 茶壶,但我也遇到了“爆炸式”的表情,而不是标志性的泡茶器具。在阅读了MDLVertexBufferLayout的文档后,我找到了解决方案,内容如下:

A mesh may store vertex data in either a structure of arrays model, where data for each vertex attribute (such as vertex position or surface normal) lies in a separate vertex buffer, or in an array of structures model, where multiple vertex attributes share the same buffer.

  • In a structure of arrays, the mesh’s vertexBuffers array contains several MDLMeshBuffer objects, and the mesh’s vertexDescriptor object contains a separate MDLVertexBufferLayout object for each buffer.

  • In an array of structures, the mesh contains a single vertex buffer, and its descriptor contains a single vertex buffer layout object. To identify which bytes in the buffer refer to which vertices and vertex attributes, use the layout’s stride together with the format and offset properties of the descriptor’s vertex attributes.

通过查看 MDLVertexDescriptor 默认实现的 .layouts.attributes 属性,他们为每个属性创建一个缓冲区类型(如上面引用的第一种情况),我想在其中使用混合模式。

我用自己的数组手动设置了 .layouts.attributes,然后,瞧,我得到了……半个 melita 壶?

Half-baked implementation... get it!?

class func setup(meshWithDevice device: MTLDevice) -> MTKMesh
{
// Allocator
let allocator = MTKMeshBufferAllocator(device: device)

// Vertex Descriptor, tells the MDLAsset how to layout the buffers
let vertexDescriptor = MDLVertexDescriptor()

// Vertex Buffer Layout, tells how many buffers will be used, and the stride of its structs
// (the init(stide: Int) crashes in the Beta)
let vertexLayout = MDLVertexBufferLayout()
vertexLayout.stride = MemoryLayout<Vertex>.size

// Apply the Layouts
vertexDescriptor.layouts = [vertexLayout]

// Apply the attributes, in my case, position and normal (float4 x2)
vertexDescriptor.attributes =
[
MDLVertexAttribute(name: MDLVertexAttributePosition, format: MDLVertexFormat.float4, offset: 0, bufferIndex: 0),
MDLVertexAttribute(name: MDLVertexAttributeNormal, format: MDLVertexFormat.float4, offset: MemoryLayout<float4>.size, bufferIndex: 0)
]

var error : NSError? = nil

// Load the teapot
let asset = MDLAsset(url: Bundle.main.url(forResource: "teapot", withExtension: "obj")!, vertexDescriptor: vertexDescriptor, bufferAllocator: allocator, preserveTopology: true, error: &error)

if let error = error
{
print(error)
}

// Obtain the teapot Mesh
let teapotModel = asset.object(at: 0) as! MDLMesh

// Convert into MetalKit Mesh, insted of ModelIO
let teapot = try! MTKMesh(mesh: teapotModel, device: device)

return teapot
}

(XCode 8 Beta 6 中的 Swift 3.0)

如果我设法渲染了整个东西,我会更新我的帖子。

编辑:现在可用

Holy shi---

Whelp,错误在我这边,我的索引计数错了:

//// Buffers
renderPass.setVertexBuffer(mesh.vertexBuffers[0].buffer, offset: 0, at: 0)
renderPass.setVertexBuffer(uniformBuffer, at: 1)

let submesh = mesh.submeshes[0]
let indexSize = submesh.indexType == .uInt32 ? 4 : 2

//// Draw Indices
renderPass.drawIndexedPrimitives(submesh.primitiveType,
indexCount: submesh.indexBuffer.length / indexSize,
indexType: submesh.indexType,
indexBuffer: submesh.indexBuffer.buffer,
indexBufferOffset: 0)

问题出在 let indexSize = submesh.indexType == .uInt32 上? 4 : 2,在我在右侧执行 32 : 16 之前,但是 .length 属性以字节而不是位的形式出现,太愚蠢了。

无论如何,我设法用 Metal 加载了一个 Obj 文件,所以问题要么是:我上面提到的每个属性的单独缓冲问题,要么是您的代码中的一个完全不同的问题。

关于swift - ModelIO 框架不工作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34562300/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com