# 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 |