This shader was my first. Like a first-time dad holding his newborn, I cherish this little guy. The project itself was to create a unique shader, which is why there’s no game or anything attached to the project. I took the name a little too seriously (shadow shader – shade, haha get it?), but I feel it was good application and got my feet wet in HLSL and pixel shaders. Shadow simply simulates the sun’s rays being cast on planets, which then produce shadows behind them as they orbit the sun. This gives rise to ‘eclipse’ like situations and shadows that double-up.
Along with the shader, this project also includes a robust particle system that takes care of the planet trails and the sun’s bursting. Plus, there’s some pretty relaxing space-y background music, making this truly fit for a screensaver.
The shader is its own file, and is included into the file like an object. The shader is a scene shader – meaning that the shader goes through all of the pixels on the screen, rather than it being attached to a sprite and it only going through the sprites visible pixels. Here’s the code that incorporates the shader into the project:
The shadows, obviously are the the meat of the shader. To keep the actual shader as lightweight as possible, I pass in the edge points of the planets each frame. These could very easily be calculated in the shader. Given these points, here is how the shader calculates the shadows:
Retrospection and Postmortem
I’m proud of what I was able to accomplish with this assignment, but looking back there is much that can be streamlined to make the code not only nicer-looking, but more modular as well, especially with the increase in GPU power over the past couple of years. For one, I would pass in the radius and center of each planet. While still passing in two values per planet, this would allow the shader to be more independent of the project and be able to calculate the edge points on its own. Secondly, I would get rid of the hard-coded values to determine the edge points, and calculate these based on the given values. This refactoring would allow the shader to loop through the planets, be more removed from the project, and just be neater overall.
But that’s not all, because there is one glaring, but hidden bug. The sun is at the center of the universe, but why is it at the bottom of the screen? When the angle is within the planet’s radius’ max angle (~2 degrees or so) from plus/minus 0 (so right around zero on the unit circle), the shader freaks out because the angle of the pixel isn’t between the edge points based on the angle. The easiest way to fix this would be to introduce an edge-case and check for this for each pixel, but a better way would be to use quaternions. I looked into it for this project, and the math was way above my head, and even now too. Maybe a summer project is on the horizon.