duku 0.2.1

A Rust crate for creating graphic experiences
Documentation
# 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.

| Argument          | Short | Effect                                                     |
| ----------------- | :---: | ---------------------------------------------------------- |
| `--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.

| Name    | Options                                        | Effect                                            |
| ------- | ---------------------------------------------- | ------------------------------------------------- |
| `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.

| Name                 | Type       | Description                                                                      |
| -------------------- | ---------- | -------------------------------------------------------------------------------- |
| `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.

| Name | Type   | Description        |
| ---- | ------ | ------------------ |
| `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.

| Name             | Type   | Description                                                 |
| ---------------- | ------ | ----------------------------------------------------------- |
| `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.

| Name                 | Type                       | Description                                |
| -------------------- | -------------------------- | ------------------------------------------ |
| `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.

| Name                  | Type            | Description                            |
| --------------------- | --------------- | -------------------------------------- |
| `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

```

| Name        | Module   | Type                                                   | Description                                                          |
| ----------- | -------- | ------------------------------------------------------ | -------------------------------------------------------------------- |
| `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 |