RealityKit Instanced Rendering on visionOS

Hello,

I've been trying to leverage instanced rendering in RealityKit on visionOS but have not had success.

RealityKit states this is supported:
https://developer.apple.com/documentation/realitykit/validating-usd-files
https://developer.apple.com/videos/play/wwdc2021/10075/?time=1373
https://developer.apple.com/videos/play/wwdc2023/10099/?time=772
RealityKit Trace metrics

Validating instancing is working:
To test I made a base visionOS app with immersive space and the entity replaced with my test usdz file. I've been using the RealityKit Trace profiling template in xcode instruments in the immersive space and volume closed. This gets consistent draw call results.

If I have a single sphere mesh with one material I get one draw call, but the number of draw calls grows linearly with mesh count no matter how my entity is configured.

What I've tried

  • Create a test scene in blender, export with instancing enabled
  • Create a test scene in Reality Composer Pro using references
  • Author usda files by hand based on the OpenUSD spec
  • Programatically create a MeshResource with Contents at runtime

References
https://openusd.org/release/api/_usd__page__scenegraph_instancing.html
https://developer.apple.com/documentation/realitykit/meshresource
https://developer.apple.com/documentation/realitykit/meshresource/instance

Thank you

For more context here is a minimal RealityKit view to reproduce the test setup.

    var body: some View {
        RealityView { content in
            let material = SimpleMaterial(color: .systemPink, isMetallic: false)
            let mesh = MeshResource.generateSphere(radius: 1)
            
            // MeshResource.generateSphere creates a model with this name
            let model0 = mesh.contents.instances["MeshModel-0"]
            let modelName = model0!.model
            
            // This implementation tries to create a new MeshResource vs MeshResource.replace()
            var instances: [MeshResource.Instance] = []
            let instanceCount = 20
            for i in 1...instanceCount {
                let translation: SIMD3<Float> = [Float.random(in: 0...1),
                                                 Float.random(in: 0...1),
                                                 Float.random(in: 0...1)]
                // Nothing in the docuementation indicates what the id needs to be.
                let instance = MeshResource.Instance(
                    id: "MeshModel-\(i)",
                    model: modelName,
                    at: Transform(
                        scale: [0.05, 0.05, 0.05],
                        translation: translation).matrix)
                instances.append(instance)
            }
            var contents = MeshResource.Contents()
            contents.models = mesh.contents.models
            contents.instances = MeshInstanceCollection(instances)
            do {
                let finalMesh = try await MeshResource(from: contents)
                var spheres = ModelEntity(mesh: finalMesh, materials: [material])
                content.add(spheres)
            } catch {
                print("failed to create mesh resource \(error.localizedDescription)")
            }
            
        }
    }

Here is a screenshot of the RealityKit trace.

Maybe there is some specific requirements on a usdz file that will trigger RealityKit to used instanced rendering.

I'm struggling with the same thing, I really need instanced rendering in my app.

Is there any update on getting this working?

Finally in Vision26 there is this new API:

https://developer.apple.com/documentation/realitykit/meshinstancescomponent

referenced in

2025 realitykit WWDC: https://developer.apple.com/videos/play/wwdc2025/287/

I've been trying it and it kind of works, it reduces draw calls and memory usage but it consumes more CPU for some reason.

I've been comparing placing an array of thousands of entities in three ways:

  1. All entities are independent.
  2. All entities are one single mesh pointing to the same texture.
  3. Entities are instanced using MeshInstanceComponent.

1: Independent entities performance is terrible. Not going to elaborate.

2: Single mesh is good. Downsides:

  • There are a lot of polygons, maybe the array should be chunked so frustrum culling works.
  • Occupies some memory.
  • Large usdz file size

3: Instancing has a great performance, maybe even better than having just a single mesh + it barely uses any memory. Downsides are:

  • Increase in CPU usage. Single mesh was 0% but with instancing it was around 20%
  • Couldn't make a usdz that had instancing in it... only able to reproduce it programatically.
  • While profiling it says 1 draw call for N entities but in the "total draw calls" it is around N*2 draw calls. One single mesh would only have 1 total draw call. I don't know where this comes from.
RealityKit Instanced Rendering on visionOS
 
 
Q