Shader Demos
Ott Adermann
Project Plan
The main goal of this project is to become more familiar with writing shaders, so as to be able to create nicer looking visuals for computer games. Hopefully by the end of the journey, I am able to discern when it is a good decision to write separate shader code for objects, and that it would be as natural as writing a regular script.
If all goes well, I would like to split the milestones in half.
In the first half, I will take a look at the process of writing shaders in a lower level environment, which will include working with a 3D API.
I have initially chosen Vulkan to be this API for two main reasons. The first is that Vulkan supposedly operates closer to the way graphics cards actually work these days, as opposed to OpenGL, which has a lot of weird things left in it from the near 30 years it has been in use. For these same reasons, Vulkan is generally also supposed to be faster. The second is that Vulkan is a new API, and because it was first announced as the next generation OpenGL it might very well mostly replace OpenGL in a few years or a decade.
The third, but minor reason is that Vulkan, like OpenGL and WebGL uses GLSL as its shader language. They're also the APIs that are collectively gaining popularity and that run on multiple operating systems, such as Windows, Linux, Mac, and Android, as opposed to HLSL, which is used by Microsoft's Direct3D, is losing popularity, and runs only on Windows.
A complication I can potentially foresee arising is that Vulkan might be more difficult than OpenGL. In the case that dealing with Vulkan proves to be too time consuming, I will switch to using WebGL and Three.js, which should allow for more focus in just dealing with shaders.
I would also note that I will be dealing with Vulkan in C++, and (in the case Vulkan proves to be too difficult) with WebGL in Javascript, both of which I've used before, but neither of which I'm comfortable with, so that is an additional layer of difficulty for myself.
In the second half, I'll try out shaders in a higher level environment, namely Unity.
Unity will allow me to basically skip all of the hassle of dealing with an API directly, as well as allowing for much faster creation of the world in which I can develop, test, and showcase the various shaders.
Unity uses a different language for its shaders that is based on HLSL, and is translated into other shader languages. Unity also has what they call a "surface shader" that isn't an actual shader in the graphics pipeline, but it allows for tweaking the look of objects without changing the overall lighting Unity provides out of the box.
I also hope to have time to check out two big new graphics-related features in Unity 2018. One being the Scriptable Render Pipeline, which allows users to define their own rendering configurations in C#, which will hopefully be a much less complicated process than doing that directly in the API. The other being the Unity Shader Graph, which enables creating shaders without writing any code at all, but instead through a visual interface.
I am curious to see how these higher level options compare to doing similar stuff directly in the API / shader code.
These two halves may be split unequally, depending on how the project develops. Since I am mostly unfamiliar with the technologies I will be using, it's very hard to estimate how long various things will take me and how far I can get.
During the project I will both be learning how to write code for the various shaders, but also what practical purposes each of these shaders could be used for. As such, I don't yet have a list of things I want to try my hand at implementing.
I will of course be looking at vertex and fragment shaders, but possibly also tesselators and geometry shaders, as well as Unity's unique surface shader.
Milestone 1 (09.03)
The mighty triangle
Goals
The goal of the first milestone is to get an application running in Vulkan. That application has to display a colored triangle at the very least. While that may seem like a very easy goal, there is actually a lot of setup work to be done before a Vulkan application can be launched. It is my intention to go over the entire setup process step-by-step and gain at least some understanding of what each step is necessary for. Further complications include my relative inexperience with C++, the skills of which I will also be developing during this milestone.
Development notes and results
I started off trying to follow the suggestion of skipping learning C++, and instead writing code for Vulkan in a more familiar language, C#, by using bindings. I found three implementations of that, but each of those had some problems. For one, all were marked as pre-release, indicating there was still work to be done on them. I found no documentation on any of those that would indicate how they should be used. And for the one that I actually tried to get working regardless, VkSharp, their own example code didn't even work due to what I can assume was some problem regarding differing versions of things. Time spent, no progress made.
So I continued on the previously planned path and worked through the cplusplus.com tutorial with moderate haste. A lot was familiar (although with notably different syntax) from having learned other languages in the past, but C++ also had some concepts that I had to familiarize myself with, the most prominent one being pointers.
Finally, I could download Vulkan, set up my development environment in Visual Studio, and start following the tutorial I had picked out.
Sadly, by this time, the deadline was already close, so I just had time to skim over the tutorial to meet the requirements for the first milestone. It does seem like a very good tutorial though, and despite all the scary syntax, it makes everything seem easy. It takes time to explain everything being done, and also provides a bit of background information.
So the result of the first milestone, as promised:

Milestone 2 (23.03)
Vertex and Fragment Shaders
Goals
During the second milestone I will be finishing with the tutorial I started in the last milestone. As the title of this milestone suggests, I will also be taking a longer look into vertex and fragment shaders.
While even the triangle rendering application includes some form of vertex and fragment shaders, as do most all applications that display anything, I will be making at least one fragment shader that displays something different than just color, basic lighting, or textures, and at least one vertex shader that does something different than just the usual transformations to post-projection space.
Current possibilities for fragment shaders that I've thought of include:
- infinite detail "textures"
- texture combining
- a lighting model with support for more advanced features like roughness, metallic, and bump maps
- maybe some other interesting ideas you or the internet have
And my current ideas for vertex shaders:
- mesh distortion (most everything falls under this category, maybe I can animate a flag, or make some flora sway in the wind)
- I've no idea how to do this, but I want to
Development notes and results