Hello, I’m Xor. As a graphics programmer, my job is actually to make pixels prettier utilizing math formulation. I work on
video results like lighting, reflections, post-processing, and extra for video games and animated backgrounds in software program.
For enjoyable, I wish to unwind by writing compact little shader packages that slot in a “tweet” (280 characters or much less).
You could have seen a few of these posted on X/Twitter. The method of shrinking code whereas sustaining its performance
is named “code golf.”
Right here’s an animated galaxy I wrote in simply 197 characters of GLSL code:
This little piece of code runs in actual time for each pixel on the display and generates a novel output shade utilizing
some fancy math and logic. I construct these demos utilizing a device known as
Twigl.app
, an internet shader editor designed for sharing mini-shaders. It makes exporting movies tremendous simple, and in its
“geekiest” mode, it additionally takes care of the generic header code and shortens built-in variable names.
I even managed to suit a voxel DDA raytracer with edge detection into simply 190 characters:
At present, I’d like to clarify why I make these, share my creation course of, and present you how one can attempt it your self if
you’re . Let’s begin with the “why.”
Motivation
Why do I write these? Properly, there are a number of elements. Since I like lists, I’ll go forward and current them so as of
relevance:
-
Curiosity and Ardour
: Generally I get struck by a brand new concept and simply wish to mess around with it. I like Twigl as a result of it helps decrease my
expectations and lets me begin doodling. There’s much less room for overplanning, and it’s tremendous simple to leap in. -
Studying and Discovery
: Working inside constraints forces me to assume by way of issues otherwise. By optimizing for code dimension, I typically
discover methods to simplify or approximate. It doesn’t at all times result in extra performant code (however typically it does) and I’ve
discovered easy methods to squeeze essentially the most out of each byte. Having little or no code makes it simpler to experiment with
formulation and variations with out getting overwhelmed. -
Problem
: Writing tiny code is each difficult and stimulating. It retains my mind sharp, and I’m continually growing new
abilities. It’s mainly turn into a recreation for me. I’ve unintentionally discovered a ton of math whereas attempting to resolve these
technical issues. -
Group
: I’ve linked with so many fascinating folks by way of this course of—artists, designers, math of us, recreation devs,
engineers, tech fans, and extra. Sharing my work has led to some thrilling encounters. (Extra on some notable
folks later!)
So, briefly, it’s enjoyable, thought-provoking, and interesting, and it’s a good way to spark curiosity in graphics
programming. Now, what even is a shader?
Shader Introduction
In case you haven’t heard of shaders earlier than, they’re packages that run on the GPU (Graphics Processing Unit) as a substitute
of the CPU (Central Processing Unit). CPUs excel at difficult or branching operations, that are computed
sequentially, separately (I’m simplifying right here). GPUs are designed to course of billions or trillions of predictable
operations per second in parallel. This seems like rather a lot, however a 4K display at 60 frames per second outputs practically 500M
pixels per second. Every pixel may have 100s or 1,000s of operations, to not point out anything the GPU may be
used for.
There are a number of several types of shaders: vertex shaders, fragment shaders, compute shaders, and extra, however these
tweet shaders are particularly fragment shaders, often known as “pixel shaders,” as a result of they run on each pixel. In
essence, fragment shaders take the enter fragment coordinates and output a shade and opacity (or alpha). Fragment
coordinates provide the place of the middle of every pixel on display, so (0.5, 0.5) is the bottom-left (or
top-left). One pixel to the fitting is (1.5, 0.5), and so forth to (width – 0.5, peak – 0.5). The coordinates variable is
known as “FC” in Twigl. The output shade, “o”, has 4 RGBA parts: crimson, inexperienced, blue, and alpha, every starting from 0.0
to 1.0.
(1.0, 1.0, 1.0, 1.0)
is pure white,
(0.0, 0.0, 0.0, 1.0)
is opaque black, and
(1.0, 0.0, 0.0, 1.0)
is pure crimson within the RGBA shade format. From right here, you possibly can already make easy shade gradients:
o = vec4(0.0, FC.y/100.0, 0.0, 1.0)
;
Bear in mind, that is run on each pixel, so every pixel can have a novel Fragment Coordinate. That formulation makes a
easy gradient that begins black on the backside of the display (FC.y = 0.0), and the inexperienced output worth reaches 1.0
when FC.y reaches 100.0.
So you’ve an output shade “o”, the enter fragment coordinates “FC”, and 4 “uniform” inputs that are shared amongst
all pixels: “r” is the shader display decision in pixels, “t” is the time in seconds, and in addition the much less generally used
mouse place “m” and the backbuffer texture “b”. And that’s the core of it! From there, it’s quite a lot of math and logic
to manage the output colours and generate cool photographs.
I’m going to skip forward a bit, however if you happen to’re interested by studying extra, attempt
beginning right here
!
My Course of
Folks typically ask me whether or not I write my shaders in a compact kind from the beginning or if I write them expanded after which
cut back the code afterward. The reply is the previous. I’ve practiced code golf a lot that I discover it simpler to
prototype concepts in compact kind, and I have a tendency to not get misplaced in tiny shaders. Code golf shaders requires discovering the
proper steadiness between code dimension, render efficiency, inventive attraction, design, and mathematical operate. It’s a
delicate steadiness that undoubtedly challenges each side of my mind. I’ve discovered a ton about math, artwork, and design
by way of writing these!
To begin one, you want an concept. When writing the “Milky” stars shader, I knew I needed to create some sort of galaxy, in order that was my preliminary spark.
My shaders usually begin with centering and scaling in order that they give the impression of being good at varied resolutions and facet ratios. For the celebs, I looped by way of 100 level lights revolving across the middle. I really like glowing results, and they’re fairly simple to create. You simply must know the gap from the present pixel to the sunshine supply and use the inverse for the pixel brightness (shut pixels are brighter, far pixels are darker).
I performed round with the positions of the particles utilizing some trigonometry and gave the disk a slight skew. For the coloring, I really like to make use of some sine waves with a section shift for the RGB channels. Sine waves are additionally helpful for selecting pseudo-random numbers, in order that’s how I choose the colours for every star. Utilizing the sine formulation, you will get palettes like these:

I ended up with a slight alteration of the one second from the left. It has a pleasant vary of temperatures and brightness. I additionally added some variation to the star brightness, which made the picture rather more fascinating to have a look at.
Subsequent, I utilized some tonemapping with the hyperbolic tangent operate for dimension. Tonemapping prevents the tough overexposure and hue shifts that occur when a shade channel hits its most brightness worth (left is unique, proper is with tonemapping):

Any good shader that has Excessive Dynamic Vary lighting ought to apply some tonemapping, and tweet shaders aren’t any
exception! Lastly, I performed with animation. It may have revolved or twisted, however in the long run, I favored the
contraction impact most. I additionally created a loop in order that new stars light in when the previous stars reached the middle. You
can examine my design course of in
extra element right here
!
Code {Golfing}
As you possibly can think about, there are lots of of little strategies that I’ve developed (and proceed to find) within the
strategy of shrinking the code down, however I can provide the abridged model! My generalized code-golfing course of can
be listed like so:
-
Cut back names:
It could be difficult initially, however you will get used to single-letter variables and performance names. You might
generally neglect what variables are for, however that is truly useful for code golf. It forces you to reread your
code, and also you’ll typically discover higher methods to jot down it when doing so. Like anything, your reminiscence will enhance with
apply, and over time you’ll set up some requirements (for me: p = place, c = shade, O = frag output, I =
enter, and many others.). -
Cut back numbers:
That is fairly self-explanatory.
1.0 == 1.
,
1000.0 == 1e3
. Don’t neglect that with vector constructors, you should use any information kind as an enter, and it will get transformed (“solid”)
to the brand new kind:
vec4(1.0, 1.0, 1.0, 1.0) == vec4(1)
. When you’re multiplying by
10.0
, you can as a substitute divide by
.1
. -
Reduce initializations:
If in case you have two floats, “x” and “y”, attempt to initialize them collectively like so:
float x = 0., y = 1.;
Search for alternatives to share information varieties. If in case you have a shade vec3 and a vec4, make them each vec4s. Keep away from
float/int conversions. -
Keep away from ifs:
If statements in GLSL take up a little bit of house, particularly if you happen to want an
else if
. Attempt utilizing a ternary as a substitute. For instance:
if (x>y) O = vec4(1,0,0,1); else O = vec4(0,1,0,1);
turns into
O = x>y ? vec4(1,0,0,1) : vec4(0,1,0,1);
. A lot shorter, and there’s rather a lot you are able to do with it. You’ll be able to even set a number of variables between
?
and
:
. -
for(;;) > whereas():
for
and
whereas
use the identical variety of characters, however
for
has a spot for initializing (earlier than the primary semicolon) and a spot for the ultimate step after every iteration (after
the final semicolon). These are free slots that can be utilized for traces that might in any other case have to finish with a
semicolon. Additionally, keep away from utilizing
break
, and use the situation spot as a substitute! You may also take away the brackets if every line ends with a comma (so it doesn’t
work with nested
for
-loops).
Past that, I exploit some operate substitutions to scale back the code additional. Extra on that
over right here
!
I’ve put collectively a
ShaderToy demo
with some further variables, formatting, and feedback for readability. Each shader is totally different and requires utilizing
totally different strategies, approximations, and ideas, however that’s exactly what makes it so enjoyable for me! I’m nonetheless
studying new stuff practically each day!
Questions and Solutions
Listed here are some questions I used to be requested on X.
Do you’ve a favourite “trick” or “method”? If that’s the case, what’s it?
I’m going by way of phases. I cherished
Bokeh DoF
, then
volumetric shadows and fractals
, however at the moment, my favourite needs to be ”
turbulence
.” It may be used for some superior
magic results
,
clouds
, or
fireplace
.
How did you develop the instinct for associated maths?
It takes a number of time and persistence. I needed to push by way of many instances after I thought a subject was over my head. When you
take it in small items, take breaks, and sleep on it, you possibly can be taught rather a lot! I wrote about a number of the
conceptualization strategies
that I’ve picked up over time. That may prevent a while!
Do you begin writing the shader in code-golfing mode, or is it a course of till you attain essentially the most optimized code? Which is one of the best editor for regular shaders and for code-golfing shaders?
Sure, I write in code-golfing mode as a result of I’ve developed an instinct for it, and it feels sooner to prototype at this
level. I nonetheless should refine the code after I discover a look that I like, although. I’m a giant fan of Twigl.app, however
ShaderToy is nice too. ShaderToy is greatest for its neighborhood and wealth of data. I attempt to use it when explaining
my tweet shaders.
How did you begin writing cool shaders, and what did you employ to be taught it?
Properly, I’ll clarify extra about my background later, nevertheless it began with an curiosity in recreation improvement. Shaders have
tons of functions in online game graphics—that’s what sparked my curiosity to be taught.
Do you’ve regrets associated to sacrificing readability?
Nope. I’m extra involved with dimension optimizations that result in slower code, however I don’t thoughts the unreadable code. To
me, that’s a part of the magic of it.
What’s your background that obtained you to the purpose the place you can successfully be taught the fabric?
It’s story time…
My Story
Rising up, I used to be interested by video video games, particularly these with “fancy” 3D graphics. After I was round 10, my pal confirmed me a device known as GameMaker. I tinkered round with it and discovered a number of the fundamentals of drag ‘n’ drop programming, variables, and conditionals.
Over time, I began experimenting with 3D graphics in GM, regardless that it was (and nonetheless is) primarily a 2D recreation engine. It was sufficient to be taught the fundamentals of how 3D rendering works and the render pipeline. Later, GameMaker launched this factor known as “shaders,” which allowed builders to create extra superior results. On the time, there weren’t many sources accessible, so it took some time for me to choose it up. I began posting my shaders on the GameMaker boards and obtained some useful suggestions from the neighborhood (shoutout to “xygthop3” for his useful examples)!
Recreation improvement was an incredible place to study shaders as a result of you’ve efficiency constraints (you don’t need a recreation to stutter), and also you be taught rather a lot about all the rendering course of in that context. In 2014, I began posting my earliest shader tutorials, sharing strategies as I discovered them. The early tutorials weren’t nice, however I’m glad I wrote them. In 2015, I began exploring ShaderToy, and that’s the place my abilities actually developed.
There have been so many nice examples to be taught from, and it was a very good place to get suggestions on my concepts. In 2021, I launched a brand new introductory tutorial sequence for GameMaker with GLSL 1.00. Now I submit extra generalized tutorials on all types of graphics matters, starting from math to artwork to design to code and extra. That is undoubtedly my greatest sequence but, they usually proceed to get higher. In case you are interested by video video games and graphics, I extremely advocate beginning with GameMaker or Godot. They’re comparatively simple to be taught whereas nonetheless highly effective sufficient to show you the ropes. If software program or internet dev is extra your factor, you possibly can’t go improper with ShaderToy or compute.toys.
Listed here are a number of the nice individuals who have helped me, instantly or not directly, alongside the best way:
xygthop3 – This man’s free shader examples had been most likely the best assist alongside the best way. His examples had been a pivotal level in my understanding of quite a lot of graphics strategies, so thanks, Michael!
Inigo Quilez – Inigo is the writer of ShaderToy and the king of raymarching. His Signed Distance Subject features are nonetheless foundational to today. An absolute legend!
Fabrice Neyret – Fabrice might be one of the best shader code golfer there’s, and plenty of shaders are impressed by his work. He has taught me so many strategies over time.
Yonatan “zozuar” – One other main inspiration for me. Yonatan’s work satisfied me to attempt code golf for actual on Twitter, and his mind is wonderful.
Yohei Nishitsuji – This man is a legend relating to tiny fractals. Love his work. Yohei additionally wrote Rendering the Simulation Concept: Exploring Fractals, GLSL, and the Nature of Actuality right here on Codrops.
I’m certain there are lots of others whose names are eluding me for the time being, however I wish to thank all the shader
neighborhood for his or her suggestions and encouragement.
Arsenal
I’ll wrap this up with just a few of my favourite tweet shaders to this point:
If you wish to see extra, yow will discover lots of on my private web site, my X , Bluesky, or Instagram. To be taught extra about shaders, attempt my tutorials , and if you wish to rent me for customized work, go right here.
Thanks for studying! Have an incredible day!
-Xor