I told this story briefly on Facebook before, but I wanted to tell it again as a full-fledged Picture of the Week. I think the full story is worth reading, even if it gets technical, so I hope you can survive those technical parts and read through.
When I first joined the Google Stadia team in 2019, it was a bit intimidating. I was joining a team that had a mix of people, some with decades of experience in the video game industry. Because of this, I didn't want to come in as their manager right away -- I wanted to spend some time in the trenches, writing code and getting to know how the internal systems worked at Google. So, I joined the team as a senior level developer. Because of this, I felt I needed to prove myself to the team in some ways. My chance to do that came fairly quickly, as it turns out. The team lead for the Graphics Tools team had an idea to hold a series of friendly coding competitions. It was a way of getting the entire team to be familiar with how video game engines work under the hood. Each competition would involve writing or modifying a part of the video game engine that the team lead had started writing. The first competition was a Shader Jam, and the directions were straightforward: Write a fragment shader from scratch that does something cool. A fragment shader is a little computer program that runs on the graphics card (GPU). What sets it apart from a regular program running on the CPU is that the shader is executed once for each pixel that is covered by a polygon on the screen. If you make one polygon that covers the entire screen, the shader will be run once for every pixel on the screen. Because of this, you have to write shaders almost backwards from how you would write a normal CPU graphics routine. In a normal program, you would set up some variables, loop through all the pixels, and modify the variables as you go along to calculate what each pixel should be. In a shader program, the only information you start with is where you are on the screen, and you have to figure out what the value of the pixel should be just based on that. The night before the contest, I was lying in bed trying to come up with some idea of what I was going to do. I should add that I had never actually written a shader before, because up until then all of my work in the TV industry had been writing CPU graphics programs. Then I had an idea: I had recently read an article on how spiral galaxies get their shape. The spiral arms are somewhat of an illusion. From astrophysics, you know that planets and stars follow elliptical orbits. It turns out that if you take a bunch of elliptical orbits, and have the angle of the major axis vary gradually by the size of the ellipse, then an overall spiral pattern emerges, even if nothing in the galaxy is following a spiral path. I decided to put that idea to the test, and see if I could simulate a spiral galaxy by plotting a bunch of ellipses and changing their angles according to their size. The next day, for the contest, we had an hour where the team lead walked us through his graphics engine to explain how it worked. Then we had two hours to write a shader and ask any questions if we needed to. First, I looked up the equations for how to approximate an ellipse, and borrowed the first function I found that looked like it would work. Then came the "backwards" part. Usually I would write a program that traced the path of the ellipse, drawing pixels along the way. Then I would loop that several times to draw different ellipses. This time my shader program was given a pixel coordinate, and I had to loop through a bunch of ellipses trying to figure out if this pixel was on or off an ellipse. I also wanted stars in my galaxy, so on each ellipse I calculated the positions of a few stars that fell on that ellipse. The end result of all my calculations was that for each pixel I calculated a value "ellipse" from 0-1, representing how much this pixel was on an ellipse. Then I calculated a value "star" from 0-1, representing how much this pixel was on a star. Then I calculated the colour of the pixel by multiplying the colour blue by "ellipse", and the colour white by "star", and adding those two values together. Shockingly, the theory worked! Just by drawing a bunch of ellipses at different angles, a spiral pattern emerged, even though I hadn't written any code to generate a spiral at all! There were just two problems: The stars near the centre of the galaxy flickered a lot. Also, the galaxy looked kind of weird with no bright cluster of stars right at the centre. I was able to fix both problems at once, finishing off my shader by calculating a central glow, which basically takes the distance from the centre, applies an exponential curve to it, and multiplies it by the colour yellow. In an attempt to preserve the code for posterity, I wrote a version of it on ShaderToy. I'm very glad I had the idea for the Galaxy Simulator before I fell asleep the night before the contest. I'm also glad I was able to figure out how to code it up under time pressure the next day! It turned out to be the winning entry in the Shader Jam, and when I became the manager of the team a few months after, my manager remarked that I had earned the respect of everyone on the team. That could very well have been because of this neat looking galaxy. It could have also been because of the shader dissassembler that I wrote for our GPU profiler, but that wasn't quite as beautiful to look at. Technical Details: This animated gif was captured from ShaderToy, since I seem to have lost the original animated gif that I captured from Stadia (yes, this Galaxy actually ran on cloud Stadia servers for one glorious afternoon).
Hosted by theorem.ca