Harfang uses [bgfx](https://bkaradzic.github.io/bgfx/index.html) as its rendering system, the cross-platform shader language is based on [GLSL](https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.1.40.pdf) with a few key differences:
* No `bool/int` uniforms, all uniforms must be `float`.
* Attributes and varyings can be accessed only from `main()` function.
* Must use `SAMPLER2D/3D/CUBE/etc.` macros instead of `sampler2D/3D/Cube/etc.` tokens.
* Must use `vec2/3/4_splat(<value>)` instead of `vec2/3/4(<value>)`.
* Must use `mtxFromCols/mtxFromRows` when constructing matrices in shaders.
* Must use `mul(x, y)` when multiplying vectors and matrices.
* Must use `varying.def.sc` to define input/output semantic and precision instead of using `attribute/in` and `varying/in/out`.
*`$input/$output` tokens must appear at the begining of shader.
## Data Flow
In a shader, vertex attributes such as position or normal are send to the vertex shader as a stream of **attributes**. The vertex shader outputs are then interpolated across the rendered primitive and passed to the fragment shader as **varyings** to compute the final pixel color.
## Writing a Shader
A shader is composed of 3 files: a definition file, the vertex and fragment source files:
-`example_vs.sc`: Source for the vertex program.
-`example_fs.sc`: Source for the fragment program.
-`example_varying.def`: Shader definition file.
Both the vertex and fragment program must declare a main function.
```glsl
void main() { ... }
```
The shader definition file must list all inputs and outputs of the shader programs and associate them with standard semantics like `POSITION` or `NORMAL` (see [HLSL Semantics](https://docs.microsoft.com/fr-fr/windows/win32/direct3dhlsl/dx-graphics-hlsl-semantics?redirectedfrom=MSDN) for a complete list).
```glsl
vec3 vNormal : NORMAL;
vec3 a_position : POSITION;
vec3 a_normal : NORMAL;
```
In the vertex program use `$input` to declare an attribute and `$output` to declare a varying. `$input/$output` tokens must appear at the begining of the program.
By convention attributes must be named one of the following: `a_position`, `a_normal`, `a_tangent`, `a_bitangent`, `a_color0`, `a_color1`, `a_color2`, `a_color3`, `a_indices`, `a_weight`, `a_texcoord0`, `a_texcoord1`, `a_texcoord2`, `a_texcoord3`, `a_texcoord4`, `a_texcoord5`, `a_texcoord6`, `a_texcoord7`, `i_data0`, `i_data1`, `i_data2`, `i_data3` or `i_data4`.
The following vertex program declares that it takes two attributes as input and outputs to a single varying.
**Note:** Attributes and varyings can only be accessed from the shader main function.
Outputs from the vertex program then become inputs to the fragment program. The fragment program outputs its result to standard GLSL variables such as `gl_FragColor` (see [GLSL Language Specifications](https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.1.40.pdf)).