lcm*_*lin 4 .obj swift metal metalkit
我试图导入3D模型文件,并使其Metal使用ModelIO和MetalKit(在OS X上10.11),但我从这些框架看到的行为(特别是ModelIO)未如预期。
我可以导入.obj文件并将它们转换为MetalKit网格而不会导致任何错误,但是网格(至少在渲染时)似乎只是一个三角形的大风扇,所有三角形都从一个点发出。下面截图中的模型应该是“Suzanne”猴头的细分版本:

在检查时,MDLSubmesh来自导入文件的顶点索引没有任何意义。连续的索引集一直引用 index 处的顶点0,有时在同一组索引中多次引用,这可以解释渲染期间的外观。我已经确认这个.obj文件可以很好地导入到其他应用程序中。
我曾尝试导入其他 3D 文件格式(所有框架都正式支持),但任何格式都不会.obj导致NSException调用MDLAsset's 时未被捕获init()。
我正在使用 Xcode 7.2 并针对 OS X 10.11。
我也遇到过类似的问题,虽然我是 Metal 的新手,但我想出了一些事情。
我试图导入 Melita 茶壶,但我也遇到了“爆炸”的面孔,而不是标志性的泡茶设备。在阅读了 的文档后MDLVertexBufferLayout,我找到了解决方案,其中写道:
网格可以将顶点数据存储在数组模型的结构中,其中每个顶点属性(例如顶点位置或表面法线)的数据位于单独的顶点缓冲区中,或者存储在结构模型的数组中,其中多个顶点属性共享相同的缓冲区。
在数组结构中,网格的 vertexBuffers 数组包含多个 MDLMeshBuffer 对象,网格的 vertexDescriptor 对象包含每个缓冲区的单独 MDLVertexBufferLayout 对象。
在结构数组中,网格包含单个顶点缓冲区,其描述符包含单个顶点缓冲区布局对象。要确定缓冲区中的哪些字节指向哪些顶点和顶点属性,请使用布局的步幅以及描述符顶点属性的格式和偏移量属性。
通过查看的默认实现的.layouts和.attributes属性MDLVertexDescriptor,他们为每个属性类型创建了一个缓冲区(如上面引用的第一种情况),我想在其中使用混合模式。
我手动设置.layouts和.attributes我自己的数组,然后,瞧我......一个梅利塔锅一半?
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
}
Run Code Online (Sandbox Code Playgroud)
(XCode 8 Beta 6 中的 Swift 3.0)
如果我设法渲染整个事情,我会更新我的帖子。
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)
Run Code Online (Sandbox Code Playgroud)
问题是let indexSize = submesh.indexType == .uInt32 ? 4 : 2, 在我32 : 16在右侧做之前,但是.length属性是字节而不是位,太愚蠢了。
无论如何,我设法用 Metal 加载了一个 Obj 文件,所以问题要么是:我上面提到的每个属性的单独缓冲的问题,要么是代码中完全不同的问题。
| 归档时间: |
|
| 查看次数: |
959 次 |
| 最近记录: |