MDLVoxelArray performance

I've been playing around with the MDLVoxelArray functionality in iOS, to create a mesh algorithmically via voxels.

Currently I create the voxel array like this:
Code Block
let minBounds = vector_float3(x: 0.0, y: 0.0, z: 0.0)
let maxBounds = vector_float3(x: Float(width), y: Float(height), z: Float(maxDepth))
let boundingBox = MDLAxisAlignedBoundingBox(maxBounds: maxBounds, minBounds: minBounds)
let voxels = MDLVoxelArray(data: Data(capacity: MemoryLayout<MDLVoxelIndex>.size * width * height * depth), boundingBox: boundingBox, voxelExtent: 1.0)

Then I populate it with indices:
Code Block
var index = MDLVoxelIndex(x: 0, y: 0, z: 0, w: 0)
for i in 0 ..< height {
for j in 0 ..< width {
index.x = Int32(j)
index.y = Int32(i)
let depth = Int32(heightMap[j][i])
let midPoint = depth / 2
for k in 0 ... depth {
// w should be 0 at the surface and increase in magnitude towards the middle
let w = abs(k - midPoint) - midPoint
index.z = k
index.w = w
voxels.setVoxelAtIndex(index)
}
}
}

Later I then convert the MDLVoxelArray to a mesh and save it out to a USDZ file. It works (and produces pretty nice results, actually) but it's really slow and gets progressively slower and slower as it iterates further and further.

I'm finding very few examples / little documentation about MDLVoxelArrays online, so my question is:

Is this the right way to go about creating and populating the voxel array? I was just guessing at how to give it an initial capacity when populating the Data object, but am imagining that might not be correct.

Any tips would also be welcome on how to go about profiling why it's slow. I'm not sure what tools are available for diagnosing performance bottlenecks when they're inside Apple's internal APIs like this?
Post not yet marked as solved Up vote post of andygeers Down vote post of andygeers
674 views

Replies

I’m hacking away at this. I know this is months old and you’ve probably already solved it. The fastest I’ve found is mesh to voxel. I can’t top that algorithmically yet even with multithreading. But now you need meshes and the problems that can go with that. And is there an opposite to “setvoxelatindex”? I can set them but I can’t make them go away in similar fashion. I use Boolean between two voxel arrays instead. Getting them to relate to each other properly doesn't seem very intuitive for me. The things are all “get” and no “set”. But it’s a real speed advantage versus iterating over each element.