# Vulkan Tutorial Authors - Khronos Vulkan Tutorial - Drawing a triangle - Graphics pipeline basics - Shader modules (Highlights)

## Metadata
**Review**:: [readwise.io](https://readwise.io/bookreview/39853255)
**Source**:: #from/readwise #from/reader
**Zettel**:: #zettel/fleeting
**Status**:: #x
**Authors**:: [[Vulkan Tutorial Authors]]
**Full Title**:: Khronos Vulkan Tutorial - Drawing a triangle - Graphics pipeline basics - Shader modules
**Category**:: #articles #readwise/articles
**Category Icon**:: 📰
**URL**:: [docs.vulkan.org](https://docs.vulkan.org/tutorial/latest/03_Drawing_a_triangle/02_Graphics_pipeline_basics/01_Shader_modules.html)
**Host**:: [[docs.vulkan.org]]
**Highlighted**:: [[2024-04-22]]
**Created**:: [[2024-05-05]]
## Highlights
- Unlike earlier APIs, shader code in Vulkan has to be specified in a bytecode format as opposed to human-readable syntax like [GLSL](https://registry.khronos.org/OpenGL/specs/gl/GLSLangSpec.4.60.html) and [HLSL](https://en.wikipedia.org/wiki/High-Level_Shading_Language). This bytecode format is called [SPIR-V](https://www.khronos.org/spir) and is designed to be used with both Vulkan and OpenCL (both Khronos APIs). ([View Highlight](https://read.readwise.io/read/01hw2hdmxyj2nc76f7fhc5v128)) ^709936425
- Although we can use this compiler directly via `glslangValidator.exe`, we will be using `glslc.exe` by Google instead. The advantage of `glslc` is that it uses the same parameter format as well-known compilers like GCC and Clang and includes some extra functionality like *includes*. Both of them are already included in the Vulkan SDK, so you don’t need to download anything extra. ([View Highlight](https://read.readwise.io/read/01hw2hf091zh8mxqmdm40jbv14)) ^709936495
### [](https://docs.vulkan.org/tutorial/latest/03_Drawing_a_triangle/02_Graphics_pipeline_basics/01_Shader_modules.html#_vertex_shader)Vertex shader
- A *clip coordinate* is a four dimensional vector from the vertex shader that is subsequently turned into a *normalized device coordinate* by dividing the whole vector by its last component. These normalized device coordinates are [homogeneous coordinates](https://en.wikipedia.org/wiki/Homogeneous_coordinates) that map the framebuffer to a [-1, 1] by [-1, 1] coordinate system that looks like the following: ([View Highlight](https://read.readwise.io/read/01hw2hv03n3w412dhtyx02vw2m)) ^709938027
- The Z coordinate now uses the same range as it does in Direct3D, from 0 to 1. ([View Highlight](https://read.readwise.io/read/01hw2hy5m209d65f1pmrxavebz)) ^709938178
### Fragment shader
- Unlike `gl_Position` in the vertex shader, there is no built-in variable to output a color for the current fragment. You have to specify your own output variable for each framebuffer where the `layout(location = 0)` modifier specifies the index of the framebuffer. The color red is written to this `outColor` variable that is linked to the first (and only) framebuffer at index `0`. ([View Highlight](https://read.readwise.io/read/01hw2j398f4xhftfxjqvy2wwc1)) ^709938727
- There is one more (optional) member, `pSpecializationInfo`, which we won’t be using here, but is worth discussing. It allows you to specify values for shader constants. ([View Highlight](https://read.readwise.io/read/01hw2n2ssss8a3wbpx8vbyhjte)) ^709947347