05 April 2022
To the uninitiated, shader programming can appear like magic. A few lines of code, written in a C-like language called GLSL, produce enchanting landscapes, fantastic worlds, strange sculptures, or photo-realistic renderings, often animated and rendered in real-time. How is this even possible? And how can we learn to write such shaders ourselves?
While the world of shader programming can appear to be entirely impenetrable, shader programming is actually a learnable skill, and many free resources are available to teach you how to do this. You just have to find them. I have spent the last few months digging through articles, websites, and YouTube videos trying to figure out how everything fits together, and I think I have found a set of materials that, when read and watched in the right order, constitute somewhat of an intro course to shader programming, from absolute basics to fairly advanced topics. This article is meant to present this course. One disclaimer: None of the materials presented here are my own. I’m simply pointing you to other people’s work that is freely available on the internet.
But first, before we get into the course material, let’s look at some shader outputs. For example, consider this flight through a snowy canyon landscape, written in a few hundred lines of GLSL code. Press the play button to see the animation. You can look at the source code here.
As a second example, consider this image of a greek temple. It’ll be a bit dark when you’ve just loaded the page, but press the play button and see how the image lights up and starts moving. The entire image is generated by about 600 lines of shader code, which you can see here.
Both of these shaders are hosted on the website Shadertoy, which can be thought of as the center of the world for the shader programming community. It allows you to write shaders interactively in the browser, to share those shaders with others in the community, and to look at or study the shaders other people have written.
Shadertoy is probably the best place to start writing your own shaders. The following shader is one that I wrote there after a few weeks of studying. It is animated and interactive. Click on play to see the animation, and drag with your mouse to rotate the scene. You can check out the source code here. By following the course materials I lay out here, you will be able to write similar shaders in no time.
Shadertoy is an excellent tool for interactive shader programming, but unfortunately it doesn’t come with instructions. It assumes you already know what you’re doing. So, how do we get started? Fortunately, Martijn Steinrucken from The Art of Code has made some excellent YouTube videos that walk you through the basics. So that’s where we start, “Shadertoy for absolute beginners, Part 1.”
There are three more videos in this series, Part 2, Part 3, and Part 4. I would encourage you to watch all of them. And, open an account on Shadertoy, create an empty shader, and follow along.
Now that you know the basics of shader programming and Shadertoy, let’s learn some tips and tricks. There are broadly two categories of shader programs, 2d pattern generators and 3d renderers. Experienced shader programmers are familiar with both. I suggest you start with 2d patterns, such as noise patterns and patterns with a regular structure. A good first video is this one by Martijn Steinrucken about value noise.
Then also watch the videos about Voronoi tesselation, Truchet tiling, and hexagonal tiling. There is much more to know about generating 2d patterns, but this should give you a solid basis from which to explore.
Next, let’s move on to 3d rendering. The core programming technique that is used to render realistic 3d scenes in real time is called ray marching. It is a relative of ray tracing where we only trace a single ray and apply some other approximations that enable extremely rapid rendering with excellent results. The core pieces of a ray marcher are surprisingly simple, and Martijn Steinrucken does an excellent job explaining them in this video.
After you have watched this video, I recommend you to watch this video about setting up a camera and this video about various simple shapes generated with ray marching.
Two additional concepts you should know about are soft shadows and ambient occlusion. I found decent introductions to them in these two videos from a channel called 3D Graphics From Scratch.
Now that you have some basic understanding of shaders and ray marching, you’re ready for the good stuff. Let me introduce you to Inigo Quilez, widely recognized as one of the leading figures in shader programming. He has invented many of the tricks now commonly used in ray marching, he is the co-creator of the website Shadertoy, he wrote the two shaders I included at the beginning of this article (Canyon and Greek Temple), and his website contains a treasure trove of useful articles about shader programming and other computer graphics topics.
When you start exploring his materials, I would suggest first looking over this presentation, which covers the main concepts of ray marching and which may fill some gaps you still have after watching the various videos I recommended. Then, you can proceed to more specialized material, for example this article about calculating normals or this article about generating soft shadows.
Inigo Quilez also has a YouTube channel. While he doesn’t post that frequently, the material he does post tends to be excellent. For example, I would encourage you to watch this three-hour (!) live stream where he codes the Greek Temple shader from scratch:
After you have completed this video, you may want to watch the live coding of “Spherical gears,” which comes in two parts, two hours each:
One resource that is commonly mentioned but that I haven’t drawn on much is The Book of Shaders by Patricio Gonzalez Vivo and Jen Lowe. I don’t normally recommend the book because as far as I can tell it is incomplete. Just when the material is getting interesting the book just stops. So be aware of this. Nevertheless, the chapters that are available are excellent, and you can most likely benefit from reading them.
Finally, I want to leave you with a list of useful code examples from which you can copy and paste into your own projects. All examples I list here have a permissive license (mostly MIT), and many of them have been written by Inigo Quilez.
That’s it for today. I hope you found this useful, and I’m looking forward to seeing any shaders written based on the materials presented here.