I am translating an app I have created from Metal to RealityKit because it was too difficult to hand-roll raycasting and transformations in pure Metal AR application. Instead of rendering camera feed and point cloud data onto a MTLView via command encoder, I need to use an ARView (via RealityKit) so that RealityKit can power the spacial transformations of the AR objects.
I am trying to use Custom Materials in RealityKit to render the metal geometry and surface shaders on top of a plane. However, this standard plane only has 4 vertices. For my geometry modifier to work, I need a couple thousand vertices on the plane.
However, when I made my own custom mesh using the code from codingxr.com (below), there is so much lag when running the app. I need lots of vertices so that I can access these vertices in the geometry shader modifier.
Is there a way to create a performant many thousand vertices mesh in RealityKit?
Or is there a way to make Metal and RealityKit to work in the same scene so that I can render to a MTKView but also take advantage of the power of ARView?
private func buildMesh(numCells: simd_int2, cellSize: Float) -> ModelEntity {
var positions: [simd_float3] = []
var textureCoordinates: [simd_float2] = []
var triangleIndices: [UInt32] = []
let size: simd_float2 = [Float(numCells.x) * cellSize, Float(numCells.y) * cellSize]
// Offset is used to make the origin in the center
let offset: simd_float2 = [size.x / 2, size.y / 2]
var i: UInt32 = 0
for row in 0..<numCells.y {
for col in 0..<numCells.x {
let x = (Float(col) * cellSize) - offset.x
let z = (Float(row) * cellSize) - offset.y
positions.append([x, 0, z])
positions.append([x + cellSize, 0, z])
positions.append([x, 0, z + cellSize])
positions.append([x + cellSize, 0, z + cellSize])
textureCoordinates.append([0.0, 0.0])
textureCoordinates.append([1.0, 0.0])
textureCoordinates.append([0.0, 1.0])
textureCoordinates.append([1.0, 1.0])
// Triangle 1
triangleIndices.append(i)
triangleIndices.append(i + 2)
triangleIndices.append(i + 1)
// Triangle 2
triangleIndices.append(i + 1)
triangleIndices.append(i + 2)
triangleIndices.append(i + 3)
i += 4
}
}
var descriptor = MeshDescriptor(name: "proceduralMesh")
descriptor.positions = MeshBuffer(positions)
descriptor.primitives = .triangles(triangleIndices)
descriptor.textureCoordinates = MeshBuffer(textureCoordinates)
var material = PhysicallyBasedMaterial()
material.baseColor = .init(tint: .white, texture: .init(try! .load(named: "base_color")))
material.normal = .init(texture: .init(try! .load(named: "normal")))
let mesh = try! MeshResource.generate(from: [descriptor])
return ModelEntity(mesh: mesh, materials: [material])
}