`MTKView` on visionOS

Is MTKView intentionally unavailable on visionOS or is this an issue with the current beta?

  • My guess is that MTKView may wrap apis that conflict with xrOS, akin to UIScreen.main.bounds.

    In the view controller's view

    public var metalLayer = CAMetalLayer() override func viewDidAppear(_ animated: Bool) { ... view.layer.addSublayer(pipeline.metalLayer) } and manually replace drawableSizeWillChange public func resize(_ viewSize: CGSize, _ scale: CGFloat) {

    ... metalLayer.contentsScale = scale metalLayer.drawableSize = viewSize }

Add a Comment

Replies

Not an engineer, but my guess is that using Metal at the moment is really different to set-up and doesn’t involve using a straight UI/NSView-style application. Rather, you call into compositorservices as in this talk: https://developer.apple.com/videos/play/wwdc2023/10089/

  • Assuming you just want to use it in 2D, MTKView is built on CAMetalLayer which is available on visionOS.

    Might be they forgot to put it in. It wasn't on tvOS originally either, but added later. It is easy enough to recreate it from scratch. Lots of examples online for those that needed more control. I was able to build my own version on visionOS with no issues.

Add a Comment

Oops, wrong reply field:

My guess is that MTKView may wrap apis that conflict with xrOS, akin to UIScreen.main.bounds.

In the view controller's view

 public var metalLayer = CAMetalLayer() 
override func viewDidAppear(_ animated: Bool) { ...
 view.layer.addSublayer(pipeline.metalLayer) } 

and manually replace drawableSizeWillChange

public func resize(_ viewSize: CGSize, _ scale: CGFloat) { ... 
metalLayer.contentsScale = scale 
metalLayer.drawableSize = viewSize } 
  • This setup works, tho I get: "frameBufferOnly texture not supported for compute." Update: metalLayer.framebufferOnly = false got rid of this error.

Add a Comment

It doesn't support MTKView because MTKView is designed to provide a 2-dimensional view to project 3D graphics into.

Instead, you want to show a 3-dimensional view directly. You do this by using a new framework called Compositor Services to set up your metal rendering surface. To see how this works:

  • Create a new visionOS app project in Xcode.
  • In the project options under "Immersive Space Renderer", choose "Metal".
  • Continue creating the project.

The code you're interested in is in the file <YourProjectName>App.swift and Renderer.swift. If you already understand Metal it should be pretty straightforward once you figure out the Compositor Services APIs.

Note that Metal apps don't support passthrough video at the moment, in case that's something you need.

Hope this helps.

  • Disagree.

    I have no idea why do you figure out that a 2-dimensional view to project 3D graphics is not something you would want to do in Vision Pro - after all, being able to play regular games in a really, really big "screen" inside a VR/AR headset is one of many applications of VR/AR.

    As a matter of fact, I'm in need of such a thing myself - my project allows the user to play a game in immersive and non-immersive mode. Would be nice if Apple allowed Metal to render to VisionOS windows...

Add a Comment

MTKView uses CA/NSDisplayLink, but visionOS is driving the compositor. There's little point too, since you need the drawables from vision (side-by-side or layered).