Day 6 (Dec 19, 2020) ~~~ Creating Shaders for the Vulkan Graphics Pipeline - kwilson33/learning-vulkan GitHub Wiki
Progress Today
I made it through these pages today of the official Vulkan tutorial. I started the Graphics pipeline basics part of Drawing a triangle after a 1 day break.
- Drawing a triangle --> Graphics pipeline basics --> Introduction
- Drawing a triangle --> Graphics pipeline basics --> Shader modules
Here are some major takeaways
1. The graphics pipeline in Vulkan is almost completely immutable, unlike older APIs like OpenGL and Direct3D,
- This means that you will have to create multiple pipelines to perform different combinations of states you want to use. For example, one pipeline may include the
Fragment shader
while another won't. - This takes time, but because all the steps are known in advance the driver can optimize it much better/faster (
ahead of time compilation
vsjust in time compilation
)
fixed-function
stages vs programmable
stages,
2. The graphics pipeline in Vulkan and
Image from the Vulkan tutorial
- The yellow stages, like the
Fragment shader
areprogrammable
which means you can use your own code to do the operations exactly as you want. - On the other hand, green stages, like
Rasterization
arefixed-function
stages meaning you can tweak their operations a little using parameters, but the way they work is predefined by the Vulkan API.
geometry shader
(a programmable
stage) is not used much in today's applications.
3. The - The geometry shader is run on every primitive (like a triangle) and can discard it or output more prims than came in.
- This is similar to the
tessellation shader
, except it's more flexible. The performance is not very good, and so it's not used often.
SPIR-V
.
4. Shader code in Vulkan has to be specified in a bytecode format called - This is different than human-readable syntax like
GLSL
(OpenGL shading language) andHLSL
(High Level Shading Language used for DirectX) SPIR-V
is designed to be used with both Vulkan and OpenCL. It is used for bothgraphics
andcompute
shaders.- The benefit is that compilers written by GPU vendors to turn shader code into company specific code are way less complex.
- Also, with a more straighforward format, Vulkan uses
SPIR-V
in hopes that shader code is more shareable and not rejected based on different companies. SPIR-V
does NOT need to be written by hand. Khronos (the company that makes Vulkan) has their own vendor-independent compiler than compilesGLSL
intoSPIR-V
. The compiler verifies that theGLSL
code is compliant with theSPIR-V
standards. There are other compilers that do this, for exampleglslc.exe
made by Google. The benefit of using Google's compiler is that it uses the same parameter format as well-known compilers like GCC and Clang, and has some extra functionality like includes. Both these compilers are included in the Vulkan SDK.
vertex shader
(VS
) takes in position and normalizes it.
5. How the -
The
VS
processes each incoming vertex. It takes in attributes like world pos, color, normal, and texture coords. -
The output of the
VS
is the final pos inclip coords
and the attributes that need to be passed onto thefragment shader
. -
A
clip coord
is a 4D vector that is then turned into anormalized device coordinate
by dividing the whole vector by its last component. -
These
normalized device coords
are homogeneous coordinates, meaning they map the framebuffer to a [-1,1] by [-1, 1] coord system, like below
Image from the Vulkan tutorial.
- For example, a
clip coord
in theVS
may look likevec4(1.0, 2.0, 3.0, 1.0)
where the first three params are X,Y,Z coords, and the last parameter is the value to divide by to get thenormalized device coord
. You can make this value 1.0 to not change anything.
entrypoints
, like main
, it's possible to combine multiple fragment shaders into one.
6. With use of different - You specify the
entrypoint
when you are specifying the pipeline stage for a shader throughVkPipelineShaderStageCreateInfo
structures.
pSpecializationInfo
field when creating shaders.
7. One optimization you can make is using the optional - When specifying the pipelne stage for a shader through
VkPipelineShaderStageCreateInfo
structures, you can use this field to specify values for shader constants. - This means you can use a single shader module where its behavior can be configured at pipeline creation, kind of like Verilog parameters.
- This is more efficient than configuring the shader using variables at render time, because the compiler can do optimizations like removing
if
statements that depend on these values.
See ya!
Now that the tutorial is getting into the graphics pipeline things are starting to make more sense. Today was probably the most fun I had with the tutorial, because it was stuff I had a little experience with from my intro to Computer Graphics class. I wrote a little GLSL in that class for shaders and today I learned how to do that (again) and in-depth what everything did (more so than my class). I also learned how to compile the shader code (GLSL
) into shader bytecode (SPIR-V
). I feel like I'm really learning a lot by going through each step painstakingly slow and it feels really good to make progress. Until tomorrow!