Chapters

Hide chapters

Metal by Tutorials

Fifth Edition · macOS 26, iOS 26 · Swift 6, Metal 3 · Xcode 26

Section I: Beginning Metal

Section 1: 10 chapters
Show chapters Hide chapters

Section II: Intermediate Metal

Section 2: 8 chapters
Show chapters Hide chapters

Section III: Advanced Metal

Section 3: 8 chapters
Show chapters Hide chapters

28. Geometry Creation with Mesh Shaders
Written by Marius Horga & Caroline Begbie

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Heads up... You’re accessing parts of this content for free, with some sections shown as scrambled text.

Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now

Now that you’ve mastered indirect GPU command encoding for generating commands for static 3D objects, you’ll discover a new pipeline where you can create or eliminate geometry procedurally on the GPU.

Grass is an ideal example. Rendering blades of grass can take your game from a fast 60fps to a barely-moving crawl. You’ll want to generate as few grass blades as possible, while still rendering lush meadows, so that you have more processing power for important things such as rendering sneaky trolls.

The Mesh Shader Pipeline

While the traditional vertex shader render pipeline is still good for standard 3D rendering, the newer mesh shader pipeline allows more fine-grained procedural geometry creation and geometry culling.

Apple’s M3 chip introduced hardware-accelerated mesh shading, keeping mesh data on chip, and improving the speed of the pipeline even more.

To refresh your memory, with the vertex shader pipeline, you pass in vertex buffers and output vertices which the GPU passes to primitive assembly to create triangles.

Blue indicates programmable functions, and pink indicates fixed GPU functions:

The vertex shader pipeline
The vertex shader pipeline

The rasterizer takes the triangles output from the vertex function and passes fragments to the fragment shader. You specify the exact number of vertices and instances that the GPU will render. There is no opportunity to add or remove vertices during a draw call in the vertex pipeline.

The mesh shader pipeline has, in place of the vertex shader stage, an optional object shader stage and a mesh shader stage.

The mesh shader pipeline
The mesh shader pipeline

You can pass in any data to the object function, such as camera data, scene data or textures. The object function then works out what geometry to build (or cull), and outputs a payload. This payload is the input to the mesh function where you create the triangles for the rasterizer. From there, the pipeline is the same as the vertex pipeline.

In this chapter, you’ll start by creating one single triangle in a mesh function. After that, you’ll generate grass blades in a tiled grid. This is where mesh shading shines. You can generate more grass blades closer to the camera, and grow sparser vegetation as the distance from the camera increases.

The Starter Project

The starter project for this chapter simply renders a triangle with three vertices using the standard vertex shader pipeline. There are three user options that load different render passes:

Kga rsusgam zciqels
Fye ymerfop wsevosl

Render a Triangle With a Mesh Shader

Rendering a triangle using a mesh shader is quite similar to using a compute shader. You set up the number of threads required, and ask the GPU to execute the mesh shader function on those threads.

The Mesh Shader Render Pass

➤ In the Render Passes folder, open MeshRenderPass.swift.

The Mesh Shader

➤ In the Shaders folder, open Shaders.metal.

Delh qpebur iijlen
Jufr jlukar oalgeq

Procedural Grass Generation

Now that you know how to render one triangle, the next step is to procedurally generate many triangles for grass.

Kamqarubq ffulh
Teyzajuzr rzupl

Odyekt xe betw pjwiujgsiavr
Axbezr ba vacn nvqoasgfuetj

1. Set up the Pipeline State Object

➤ In the Render Passes folder, open GrassRenderPass.swift and check out the code.

2. Set up the Grass Input Data

➤ In the Shaders folder, open Common.h, and add these new structures before #endif /* Common_h */:

3. The Draw

➤ In draw(commandBuffer:scene:uniforms:), replace // add code here, and bind the data to the object stage:

4. The Object Shader Function

➤ Create a new file in the Shaders folder, using the Metal File template, named GrassShaders.metal.

5. The Mesh Shader Function

With the object shader function outputting a payload of grass blades, you can create the mesh shader.

Zeqsv rxugj varduq
Neksr lpegk sugrey

Gikbuk pijoc
Tarriq wewuj

Creating Randomness

The grass is standing around like soldiers in a row. What it needs is some natural randomization for color, height, width, rotation and maybe some gentle wind movement.

Qbocwefec qhubm
Ymogvatum qzinx

Vikq bxiyw
Kakv nxagc

Meshlet Culling

An important use case for mesh shaders is rendering levels of detail. When you have models with a ton of geometry, you don’t want to render it if it’s out of the camera frustum or if it’s occluded. However, a large model might consist of many small triangles, and you might have to render the whole model if only a small part is on-screen.

Wcofdibh Stolek qtabund cugihap zeqxnohx
Vzakniwh Lmulud cpalofb xikapiy goxccuwm

Challenge

For your challenge, you’ll make the grass look more grassy and less triangular.

Lunpwatos tdick
Dewyzowij lkowh

Key Points

  • Use the standard vertex pipeline for most rendering. You can use GPU indirect command encoding for camera frustum culling. Mesh shaders are useful for generating and culling simple geometry.
  • There are two stages in the mesh shader pipeline. Firstly, the object stage is where you decide on what geometry to create or cull. Secondly, the mesh stage is where you create actual vertices.
  • In this grass rendering example, object shaders run per tile, while mesh shaders run per grass blade, with a thread for each vertex.
  • Metal Shading Language doesn’t provide a random number function. There are many different kinds of random number algorithms. The hash function used in this chapter is a commonly-used, but simple, algorithm.

Where to Go From Here?

The grass you created in this chapter is highly stylized. For more natural grass, you’ll create more vertices than just a triangle. Wind blowing across the surface will enhance the effect enormously.

Have a technical question? Want to report a bug? You can ask questions and report bugs to the book authors in our official book forum here.
© 2026 Kodeco Inc.

You’re accessing parts of this content for free, with some sections shown as scrambled text. Unlock our entire catalogue of books and courses, with a Kodeco Personal Plan.

Unlock now