# How to understand metal compute shader code?

**URL:** <https://forums.kodeco.com/t/how-to-understand-metal-compute-shader-code/178224>\
**Category:** Metal by Tutorials\
**Created:** [September 13, 2022, 5:14pm UTC](https://forums.kodeco.com/t/how-to-understand-metal-compute-shader-code/178224 "2022-09-13T17:14:51Z")\
**Posts on this page:** 8\
**Page:** 1

<div class="post-metadata">

**Author:** ![marek-kuticka](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/marek-kuticka/32/102075_2.png) [@marek-kuticka](https://forums.kodeco.com/u/marek-kuticka)\
**Post date:** [September 13, 2022, 5:14pm UTC](https://forums.kodeco.com/t/how-to-understand-metal-compute-shader-code/178224/1 "2022-09-13T17:14:51Z")

</div>

Hello @caroline

I hope this question is allowed, as it is related to a different repo/different tutorial, but it is Metal based.

and I am using Your book, to try to understand that code.

> **[GitHub - Kosalos/OSX-MarchingCubes: Swift 4.2 rendition for Mac](https://github.com/Kosalos/OSX-MarchingCubes)**
>
> Swift 4.2 rendition for Mac. Contribute to Kosalos/OSX-MarchingCubes development by creating an account on GitHub.

and related youtube video about marching cubes implementation in Swift.

what I see when I execute the app is 5 spheres, which blend into objects, if the spheres interfere with each other. what I also ( hopefully ) understand is, that if certain vertices are located within BOTH spheres, then they are not rendered, so at the end only outer shell is visible.

what I however fail to understand quite desperately is… HOW the spheres itself are rendered? I know, they are centered around those red center points… but I could never find piece of code ( and its hidden somewhere in compute shaders ), which provides vertices for these spheres.I was able to get snapshot of GPU frame, find the vertices in memory, in buffer, etc… but HOW are they calculated? if you have time and would like to help me… or anyone else. if you look at the shaders.metal code… can you see, where the spheres do get their vertices? can someone give me some short explanation to this?

many many thanks

Marek

---

<div class="post-metadata">

**Author:** ![caroline](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/caroline/32/111867_2.png) [@caroline](https://forums.kodeco.com/u/caroline)\
**Post date:** [September 14, 2022, 2:50am UTC](https://forums.kodeco.com/t/how-to-understand-metal-compute-shader-code/178224/2 "2022-09-14T02:50:01Z")

</div>

As far as I can make out, this is what is happening.

Along with the MTKView’s render delegate draw, there’s a parallel compute update going on.

In ViewController.swift, `viewDidAppear()`, a timer is set up to run `paceTimerHandler()`.

`paceTimerHandler()` performs `world.update(self)` which calls `computeShader.processBallMovement()`. This creates a separate command buffer, which has compute shaders that update `ballData`.

`world.update` then takes `ballData` and copies it to `ballPoints`.

The render loop’s `draw(in:)` calls `world.render`, which creates a vertex buffer out of `ballPoints` and renders the balls and then the cube.

---

<div class="post-metadata">

**Author:** ![marek-kuticka](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/marek-kuticka/32/102075_2.png) [@marek-kuticka](https://forums.kodeco.com/u/marek-kuticka)\
**Post date:** [September 14, 2022, 6:37am UTC](https://forums.kodeco.com/t/how-to-understand-metal-compute-shader-code/178224/3 "2022-09-14T06:37:02Z")

</div>

Thx a lot for the answer.

Can you understand There, how exactly the vertices are generated from/around these Ball points? This is what I am missing. Also… How can I control number of vertices for a Ball? And e. G. Radius?

This seems to be hidden in one of the compute shaders

Thx a lot!!

---

<div class="post-metadata">

**Author:** ![caroline](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/caroline/32/111867_2.png) [@caroline](https://forums.kodeco.com/u/caroline)\
**Post date:** [September 14, 2022, 8:25am UTC](https://forums.kodeco.com/t/how-to-understand-metal-compute-shader-code/178224/4 "2022-09-14T08:25:41Z")

</div>

I don’t know the algorithm at all, so I can only tell you what I’m seeing in the code.

If the Metal debugger doesn’t help, then I find variable and function names that look useful and do Cmd-Shift-F to search for them in the project and follow them through. Sometimes I do a print, so for example, I know that by printing out `iCount` in `Cube.render`, I can see the number of indices being rendered.

I also use Cmd-Shift-A to jump to the definition of an object.

The balls are drawn in `Cube.render`.

`Background.keyDown` shows that you can press the letter `V` to change from textured triangle to line drawing and `1` & `2` to make the spheres larger and smaller respectively. This updates `control.isoValue` or `cd.isoValue` on the GPU, which is used by the compute shaders as, I guess, the radius of the sphere.

`ComputeShader.update` runs several compute shaders. The first updates the grid and the second updates the flux points. I have no idea about the algorithm, so I guess that’s where the magic happens.

The third compute shader is `pipeline[PIPELINE_UPDATE_VERTICES]`, which runs the shader `determineVertices` where I guess the vertices are written to the buffer. That function uses eTable and tTable which are look-up tables. I don’t know what they are, but tTable values are 0 to 11, which implies that they are less than the “flux points” count of 12 (`BCOUNT`).

`GSPAN` is the size of the cube.

The 12 balls’ central point position data is created in the shader `calcBallMovement`.

Aside from that, the code is quite complex, and I don’t know the algorithm, so I don’t really understand what’s happening.

Edit: But this might help! [Polygonising a scalar field (Marching Cubes)](http://paulbourke.net/geometry/polygonise/). That explains the lookup tables at least.

---

<div class="post-metadata">

**Author:** ![marek-kuticka](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/marek-kuticka/32/102075_2.png) [@marek-kuticka](https://forums.kodeco.com/u/marek-kuticka)\
**Post date:** [September 14, 2022, 5:47pm UTC](https://forums.kodeco.com/t/how-to-understand-metal-compute-shader-code/178224/5 "2022-09-14T17:47:30Z")

</div>

Thx a lot

Probably Last question here

Those shader func have ID param As a thread\_pos\_in\_grid

Can you explain, What is the grid the function is using? If I have img, its clear. But can I tell metal to e. G. Proces s volume from 0,0,0 to 10,10,10? I am missing bit of logic here

Thx

---

<div class="post-metadata">

**Author:** ![caroline](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/caroline/32/111867_2.png) [@caroline](https://forums.kodeco.com/u/caroline)\
**Post date:** [September 14, 2022, 11:56pm UTC](https://forums.kodeco.com/t/how-to-understand-metal-compute-shader-code/178224/6 "2022-09-14T23:56:52Z")

</div>

Have you read Chapter 16, GPU Compute Programming? This chapter explains threads and thread groups. The grid is the size of whatever you process, and you decide that.

You can have a 1d, 2d or 3d grid.

The chapter code sets up a 1d grid, to process each of the vertices in turn. An image is 2d, but your app deals with volumetrics, and so is 3d. With a 3d grid, to identify the exact thread, you need the x, y and z of the thread\_position\_in\_grid.

`GSPAN` is the value for the number of threads in each direction. This is the size of the enclosing box. If you change it from 50 to 30, it’s a smaller box. By having an x, y, z, you can identify each voxel inside the enclosed box area.

---

<div class="post-metadata">

**Author:** ![marek-kuticka](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/marek-kuticka/32/102075_2.png) [@marek-kuticka](https://forums.kodeco.com/u/marek-kuticka)\
**Post date:** [September 15, 2022, 7:29am UTC](https://forums.kodeco.com/t/how-to-understand-metal-compute-shader-code/178224/7 "2022-09-15T07:29:51Z")

</div>

ok… tbh I have probably missed this, or missed the dependencies.  
so if I apply this to 183756th Minecraft clone available… as a part of learning Metal/3D graphics in general, it means, that I can freely choose size of box ( when dispatching Threads), then code will run for my given points, AND… when rendering e.g. indexed vertices ( because my box for compute shader might e.g. be 100x100x25 big, but the world might be magnitude bigger ) , I can specify base point for part of the world to be rendered, so the compute shader runs only for the relevant part of the world, that is being updated… is it like this?

thx a lot

---

<div class="post-metadata">

**Author:** ![caroline](https://assets.chunter.kodeco.com/user_avatar/forums.kodeco.com/caroline/32/111867_2.png) [@caroline](https://forums.kodeco.com/u/caroline)\
**Post date:** [September 15, 2022, 9:09am UTC](https://forums.kodeco.com/t/how-to-understand-metal-compute-shader-code/178224/8 "2022-09-15T09:09:32Z")

</div>

That isn’t a question I can answer. I do know from experience that copying code that I don’t completely understand never works in the long run.
