# dc Docs
[Simple Example](#simple-example) • [Using Compiler](#using-compiler) • [Writing Shaders](#writing-shaders)
Shader compilation for Duku
## Simple Example
```glsl
// file: shader.glsl
// configure shader
#define DEPTH test_and_write
#define SHAPE filled_triangles
#define CULL back
// specify shader output
layout(location = 0) out vec4 out_color;
// main fragment shader function
void fragment() {
// get color from bound material
vec3 color = material.a.rgb;
// output color to canvas
out_color = vec4(color, 1.0);
}
```
Can be compiled to `.spirv` or imported directly as a `.glsl`
## Using Compiler
To compile a duku `.spirv` file, you can use the CLI utilicy
`dc` downloaded from the release page or compiling the `dc` binary target from source with cargo.
```bash
$ dc test.glsl
```
Running this command will compile the `test.glsl` file into
`test.spirv` and put it relative to the input file.
#### Options
There are some additional options available to customize the compilation process.
| `--out some/path` | `-o` | will put the output in the specified directory `some/path` |
| `--help` | `-h` | will print out the help information |
| `--no-color` | n/a | will disable the colors in the output |
| `--version` | n/a | will print out the compiler version |
## Writing Shaders
The language used for writing shaders is [glsl]
with some custom additions, which will be specified
below.
#### Configuration
The first thing you need to define in each shader are these
usage options.
| `DEPTH` | `test`, `write`, `test_and_write` | defines how depth tests are gonna be applied |
| `SHAPE` | `filled_triangles`, `lined_triangles`, `lines` | defines how the vertices are gonna be interpreted |
| `CULL` | `back`, `front`, `disabled` | defines what culling method is applied |
Example:
```glsl
#define DEPTH test_and_write
#define SHAPE filled_triangles
#define CULL back
```
#### Entry Functions
In [glsl] the entry functions for both vertex and fragment
shaders are usually defined as `main`, but because for duku
both vertex and fragment shaders are written in the same file
they are defined as `vertex` and `fragment` like so:
```glsl
void fragment() {
// output fragments
}
void vertex() {
// output vertices
}
```
As the vertex shader is optional (and is usually ommited),
global constants outside these functions will
be available only in the fragment shader.
[glsl]: https://www.khronos.org/opengl/wiki/Core_Language_(GLSL)
#### Global Objects
Global objects provide data that has
been passed from the Rust code.
`world` defines values that are set for each canvas target.
| `world_to_view` | `mat4` | matrix that transforms coordinate from world to view space |
| `view_to_clip` | `mat4` | matrix that transforms coordinate from view to clip space |
| `world_to_shadow` | `mat4[4]` | matrices that transform coordinate from world to shadow space |
| `camera_position` | `vec3` | camera position in world space |
| `skybox_index` | `uint` | index for current skybox |
| `time` | `float` | time since the start of context creation |
| `lights` | `Light[4]` | lights that are in the scene |
| `ambient_color` | `vec3` | ambient light's color |
| `shadow_splits` | `vec4` | shadow map split values |
| `shadow_texels` | `vec4` | shadow map texel sizes |
| `shadow_diameters` | `vec4` | shadow map area diameters |
| `shadow_pcf` | `float` | shadow map softness value |
| `shadow_light_index` | `uint` | index of the light that casts shadows. 4 means there is no shadow casting light. |
| `exposure` | `float` | value used to do tone mapping |
`material` defines values that are set for each material.
| `a` | `vec4` | user defined value |
| `b` | `vec4` | user defined value |
| `c` | `vec4` | user defined value |
| `d` | `vec4` | user defined value |
| `e` | `vec4` | user defined value |
| `f` | `vec4` | user defined value |
| `g` | `vec4` | user defined value |
| `h` | `vec4` | user defined value |
`object` defines values that are set for each draw call.
| `local_to_world` | `mat4` | matrix that transforms coordinate from local to world space |
| `tint_color` | `vec3` | color used to tint objects |
| `sampler_index` | `uint` | sampler index |
The `Light` type is defines like this:
```glsl
struct Light {
vec3 coords;
int type;
vec4 color;
};
```
#### Fragment Shader Definitions
These global values and functions
are defined for each fragment shader.
| `in_uv` | `in vec2` | Vertex UV coordinate |
| `in_color` | `in vec4` | Vertex color |
| `in_texture` | `flat in uint` | Vertex texture |
| `in_local_position` | `in vec3` | Vertex local space coordinate |
| `in_world_position` | `in vec3` | Vertex world space coordinate |
| `in_view_position` | `in vec3` | Vertex view space coordinate |
| `in_clip_position` | `in vec4` | Vertex clip space coordinate |
| `in_shadow_position` | `in vec4[4]` | Vertex shadow space coordinates |
| `in_tbn` | `in mat3` | Vertex tangent-bitangent-normal matrix |
| `textures` | `uniform texture2D[100]` | All loaded textures |
| `samplers` | `uniform sampler[12]` | All loaded samplers |
| `cubemaps` | `uniform textureCube[100]` | All loaded cubemaps |
| `shadow_maps` | `uniform texture2D[4]` | Currently bound shadow maps |
| `tex` | `(uint, vec2) -> vec4` | Samples a texture with the current sampler |
| `cub` | `(uint, vec3 -> vec4` | Samples a cubemap |
| `tex_size` | `(uint) -> vec2` | Gets the texture's size |
#### Vertex Shader Definitions
These global values and functions
are defined for each vertex shader.
| `in_local_position` | `in vec3` | Vertex local space coordinate |
| `in_normal` | `in vec3` | Vertex normal direction |
| `in_tangent` | `in vec3` | Vertex tangent direction |
| `in_uv` | `in vec2` | Vertex UV coordinate |
| `in_color` | `in vec4` | Vertex color |
| `in_texture` | `in uint` | Vertex texture |
| `out_uv` | `out vec2` | Vertex UV coordinate |
| `out_color` | `out vec4` | Vertex color |
| `out_texture` | `flat out uint` | Vertex texture |
| `out_local_position` | `out vec3` | Vertex local space coordinate |
| `out_world_position` | `out vec3` | Vertex world space coordinate |
| `out_view_position` | `out vec3` | Vertex view space coordinate |
| `out_clip_position` | `out vec4` | Vertex clip space coordinate |
| `out_shadow_position` | `out vec4[4]` | Vertex shadow space coordinates |
| `out_tbn` | `out mat3` | Vertex tangent-bitangent-normal matrix |
#### Additional Definitions
These global and functions can be imported
by defining a module like so:
```glsl
#define SRGB
```
| `to_linear` | `SRGB` | `(float) -> float`, `(vec3) -> vec3`, `(vec4) -> vec4` | converts value to linear color space |
| `to_srgb` | `SRGB` | `(float) -> float`, `(vec3) -> vec3`, `(vec4) -> vec4` | converts value to sRGB color space |
| `shadow` | `SHADOW` | `(Light, vec3) -> float` | calculates the received shadow using the light and the normal vector |