Quasicrystals in Metal

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.

Screenshot 2019-04-30 at 19.42.18

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.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s