TEAM LICENSES: Save money and learn new skills through a Hacking with Swift+ team license >>

Current best practice for doing 2D graphics with Metal and SwiftUI

Forums > SwiftUI

Background

I already know Swift, and recently began learning Metal (on macOS). While the tutorials I found online were good for learning Metal, they all tend to use NSView etc, while I'd prefer to use SwiftUI.

The approach I found works well enough, but after watching Paul Hudson's tutorials on YouTube (in particular SwiftUI + Metal – Create special effects by building your own shaders), I now suspect my approach may be obsolete, and that I should always use the API Paul demonstrates in that video.

In the video, Paul calls methods like colorEffect and distortionEffect on a UIView, passing stuff like ShaderLibrary.passthrough().

My approach is much more involved, defining a MTKViewDelegate as a coordinator for a delegate that conforms to NSViewRepresentable and wraps the MTKView (with a draw method that uses a command encoder, and presents a drawable to a command buffer etc etc):

Was my approach made obsolete by the API Paul is using, or is that API only meant to apply filters to views?

Objective

I'm ultimately looking to make a 2D video game, with graphics like these (from ShenZhen I/O):

I'd like to write a shader that renders the bulk of the graphics as a classic tiled background, with different shader programs for rendering the screens on the in-game displays, and the monospaced text on the programmable chips etc.

I could easily write the various shaders I need, as standalone shaders, but cannot figure out the best way to combine everything (blitting the output from one shader program onto the output from another) to produce the final image.

I'd be very grateful for any advice anyone has on how to combine pixel shaders to composite 2D graphics. Thank you for taking the time.

2      

Towards the end of the video, there's a section named Generating everthing with Metal (beginning at 1:00:13). In that section, Paul creates a shader that generates an image from scratch. That got me thinking that that API might be flexible enough to do what I need, but I'm beginning to suspect it might not be.

When passing extra (user-defined) arguments to the [[stichable]] Metal functions (like Paul demonstrates in the video), can we pass buffers, textures and samplers etc (as we can with the approach I'm currently using)? If so, can we index them as attributes (as in [[buffer(0)]]) when defining the [[stichable]] function parameters?

In short, I'm just trying to establish whether the Metal integration in SwiftUI is currently flexible enough to render the graphics I've described using the SwiftUI Metal API, or if using an NSViewDelegate with a MTKView is still required for this kind of thing.

I know that Metal integration with SwiftUI is evolving, so I'm unsure if they've added an API that changes the best approach.

2      

Thanks for getting back to me.

I'm really trying to understand the API specifics. I know I need to combine the output from multiple shaders, but don't know how to do that with Swift (or Obj-C).

I asked a similar question on the official Swift Forum, and have been offered some advice there that I still need to try out.

2      

We figured it out in the other forum.

You basically need to create a multiple pipeline descriptors (and pipeline states) inside the init method, then in the draw method, you repeatedly set the pipeline state (on the encoder), as well as the dimensions and offsets for the viewport, calling drawPrimitives on the encoder for each shader (calling endEncoding once, as usual, once everything has been encoded).

2      

Hacking with Swift is sponsored by RevenueCat.

SPONSORED Take the pain out of configuring and testing your paywalls. RevenueCat's Paywalls allow you to remotely configure your entire paywall view without any code changes or app updates.

Learn more here

Sponsor Hacking with Swift and reach the world's largest Swift community!

Reply to this topic…

You need to create an account or log in to reply.

All interactions here are governed by our code of conduct.

 
Unknown user

You are not logged in

Log in or create account
 

Link copied to your pasteboard.