I recently had my attention drawn to the blog Main is Usually a Function which was discussing the art of creating quasicrystals as computer images using fairly simple rules. The blog in question uses Haskel to create a solution and rendered the result as an animated
png. The author seems quite pleased he was able to render one frame in about three seconds on a six core machine with only 474% CPU time (he had a six core machine). This looks like an excellent project to do in Metal, I thought.
Having completed the task, I am pleased to say that I can render the same image at 60 frames per second using only between 10% and 20% of the CPU (I also have six cores). Of course, all the work is being done by the graphics card, but even so, my laptop doesn’t even spin up the fan when running my code. See a run of my program here.
So What Is It?
This program is designed to render a quasicrystal-like pattern. The pattern is created by generating a sine wave (or cosine wave – it’s the same) for each point on a surface based on that point’s distance to a line drawn through the origin. The amplitude is then represented at the pixel in question by shading it in proportion to its magnitude after being corrected so the sine wave varies between 0 and 1. i.e.
y = (cos(kx) + 1) / 2
where y is the shade of the pixel, x is the perpendicular distance from the point to a straight line drawn through the origin and k = 2π/λ (λ is the wavelength). This gives the appearance of a series of parallel mave fronts. We can then make it move by adding a time component.
y = (cos(kx + ωt) + 1) / 2
where t is the time and ω is the angular velocity (ω = 2πf, f being the frequency).
The patterns generated by this program are simply a number of such waves varying in direction between 0 and π. So, if there are seven waves they have angles of 0, π/7, 2π/7, … 6π/7.
The values for each wave at each point at the given time are combined in a certain way to give an overall value between 0 and 1 and we colour the pixel at that point based on the value.
Can I See the Code?
The project is uploaded to Bitbucket. You should be able to just
git clone it and build and run it with Xcode 10.2.