How to pass variables or data to a Metal Shader in XCode

A step by step guide on creating a MTKView in a UIView and passing variables or structured data through "uniform" or "argument" buffers to the Metal shader.

Oscar de la Hera Gomez
Written by Oscar de la Hera Gomez
First published on 10/04/2023 at 11:38
Last Updated on 10/04/2023 at 14:40
<p>Three flowers that represent Swift, Metal and XCode with the text "Buffers" beneath it.</p>

A step by step guide on creating a MTKView in a UIView and passing variables or structured data through "uniform" or "argument" buffers to the Metal shader.

SubscribeCheck out our Apple Metal Resources Guide

We recommend that you clone our Open Source Swift Starter Project, checking out the main branch and carrying out the steps below. The changes can be found on the tutorial/metal/buffers branch.

git clone git@github.com:delasign/swift-starter-project.git
View RepositoryHow to create a SwiftLint enabled Swift XCode Project

What are Uniform or Argument Buffers ?

Uniform and Argument Buffers are two terms that are used for the different types of data that can be passed to a metal shader.

  • Uniform buffers are used to pass constant data that remains constant for the entire duration of a draw call or dispatch call.
  • Argument buffers are used to bundle resources and data required for a particular shader function into a single object. This allows you to group resources like textures, buffers, and samplers along with associated data (constants) needed for a specific shader invocation.
Read Apple's Metal Shading Language Specification (V3.1)

Tutorial

Step One: Setup the MTKView

<p>A screenshot of an iPhone showing a black background with a red triangle that was produced with metal.</p>

Follow the tutorial below to setup a MTKView within a UIView that shows a triangle.

How to use Metal with a UIView in Swift

Step Two: Pass Data to the Shader

<p>A screenshot of Xcode showing the MetalUIView+MetalDelegate.swift file that demonstrates how to create a buffer from a variable or a struct. The code to do this is found below.</p>

The following step demonstrates how to pass constants or structs to a Metal shader's vertex or fragment function in Swift.

This data must be defined and passed into the shader within the MetalUIView+MetalDelegate.swift file.

Please note that implementing the data within the vertex and fragment functions is described in the next step.

A | Variable

Declare a constant and create a buffer from it using code similar to the one below.

Please note that setVertexBuffer should be used to pass data to the vertex function and setFragmentBuffer should be used to pass data to the fragment function.

B | Struct

Declare a struct and create a buffer from it using code similar to the one below.

Please note that setVertexBuffer should be used to pass data to the vertex function and setFragmentBuffer should be used to pass data to the fragment function.

Step Three: Update the Shader

<p>A screenshot of Xcode showing the SampleMetalShader.metal file. The code details the changes that took place and the code can be found below.</p>

Declare the struct that you used in Step Two, Part B within the metal shader and update the vertex and fragment functions to include arguments for the functions passed in Step Two.

Please note that the number used within the buffer must match that the "index" that you wrote in Step Two (i.e. red must be buffer(1) and screenSize must be buffer(2)).

These variable or struct buffers can now be used in similar ways to the way they are used in Swift.

Step Four: Test

<p>A screenshot of an iPhone showing a triangle that's less red than it was before. It is less red because the variable that we have set for the red color is smaller than the one we set in Step One. This proves that the code works.</p>

Run the code on a device and confirm that the shader works as expected.

Looking to learn more about things you can do with Swift, Metal and XCode ?

Search our blog to find educational content on learning how to use Swift, Metal and XCode.

Search our Blog

Any Questions?

We are actively looking for feedback on how to improve this resource. Please send us a note to inquiries@delasign.com with any thoughts or feedback you may have.
SubscribeContact UsVisit our BlogView our ServicesView our Work

Partner with us

We would love to get to know you and see how we can help your organization with its goals and needs.
Let's Talk

Stay Informed

Get occasional updates about our company, research, and product launches.
Subscribe