# Shader API

## Includes

HIRO supports `#include "filename"` syntax for the mutual inclusion of shader files. The specified filename is always relative to the HIRO shader folder (located in the resource directory).

Main include files for API, that can be used in custom shaders are:

- api_definitions.glsl Contains general API definitions.

- api_vert.glsl Contains vertex-specific API definitions. Already includes api_definitions.glsl.

- api_frag.glsl Contains fragment-specific API definitions. Already includes api_definitions.glsl.

Attention

The shader build system does not support include guards. When including a file, be careful that the file was not already included in other included files.

## System Uniforms

    uint SCENE_ID;

Scene index for which the rendering was invoked. Managed automatically.

    bool USING_INSTANCING;

Whether instanced rendering is enabled. Should be set by the user, via uniform binding `ULOC_USE_INSTANCING`. See section Transformations. for more detail.

    mat4 INSTANCES[MAX_INSTANCE_COUNT];

Contains instance matrices. Should be set by the user, via uniform binding `UBIND_INSTANCING_MATRICES`.

    MatAndInv VIEWS[MAX_CAMERA_COUNT];

Contains view transformations of all cameras registered in the rendering system. Managed automatically.

    SceneData SCENES[MAX_SCENE_COUNT];

Information about all scenes registered in the rendering system. Managed automatically.

    Light LIGHTS[MAX_LIGHT_COUNT];

Information about all lights registered in the rendering system. Managed automatically.

## Custom Uniforms

Some uniform locations and uniform buffer (UBO) bindings are reserved for the rendering system. The location and binding constants are reflected in both C++ and GLSL code. C++ Definitions are located in ShaderApi.h and GLSL definitions are in api_definitions.glsl.

For user-defined uniforms, locations must use `ULOC_CUSTOM_n` definitions, where `n` is a specific location. Similar applies to UBO bindings. Here, notation `UBIND_CUSTOM_n` is used, where `n` is a binding index.

An example of use:

    1
    2
    layout (location = ULOC_CUSTOM_0) uniform vec3 my_uniform;
    layout (std140, binding = UBIND_CUSTOM_0) uniform MyStructureBlock { MyStructure my_struct; };

## Transformations

Rendering system uses several transformation steps to obtain final transformation.

Pre-instance and instance transformations should be considered only when instancing is enabled. Otherwise, only the standard model-view-projection transformation should be used.

Shader API includes these definitions for getting transformations:

### api_definitions.glsl

    bool USING_INSTANCING;

Whether instanced rendering is enabled.

    mat4 PRE_INSTANCE_MAT;
    mat4 PRE_INSTANCE_INV_MAT;

Pre-instancing matrix specified by the user in Renderer and its inverted version.

    mat4 MODEL_MAT;
    mat4 MODEL_INV_MAT;

Model matrix set via Style.transform and its inverted version.

    mat4 VIEW_MAT;
    mat4 VIEW_INV_MAT;

View matrix originating from the current camera pose and its inverted version.

    mat4 PROJ_MAT;
    mat4 PROJ_INV_MAT;

Projection matrix and its inverted version.

### api_vertex.glsl

    mat4 GetTransfInstance();

Returns full instance transformation. Returns identity when instancing is disabled.

    mat4 GetTransfModel();

Returns full instance-model transformation. Instance transformation included only if enabled.

    mat4 GetTransfView();

Returns full instance-model-view transformation. Instance transformation included only if enabled.

    mat4 GetTransfProjection();

Returns full instance-model-view-projection transformation. Instance transformation included only if enabled.

### api_frag.glsl

    vec3 GetDirectionToLight(in vec3 position_eye)

Returns (camera space) direction from point to light.

    bool IsOnDarkSide(in vec3 position_eye, in vec3 normal_eye)

Check if point is on the surface turned away from the light.

    vec3 Project(in vec3 position_eye, in mat4 projection)

Returns (camera space) direction from point to light. Resulting projection is in range <0,1> space.

    float TestShadow(in vec3 position_eye, in vec3 normal_eye);

Checks if there is shadow casted on a specified position.

    void WriteFragment(in vec3 position_eye, in vec3 normal_eye, in Material material);

Writes fragment to deferred buffers, specifying the position and normal of a fragment in camera coordinate space - right after applying view matrix (see section Transformations for more detail).

    void WriteFragment(in vec3 color);

Writes fragment to deferred buffers, that will not be shaded and in the final render, the color will appear unmodified.

## Examples

### Vertex Shader

Include file api_vert.glsl which provides interface functions for vertex shaders.

An example of a very simple vertex shader:

     1
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    #version 430
    #include "api_vert.glsl"

    layout (location = 0) in vec3 in_position;
    layout (location = ULOC_CUSTOM_0) uniform vec3 color;

    void main ()
    {
      out_color = in_color;
      gl_Position = GetTransfProjection() * vec4(in_position, 1.0);
    }

### Fragment Shader

The render system uses deferred shading. Include file api_frag.glsl which provides interface functions for fragment shaders.

An example of a very simple fragment shader:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    #version 430
    #include "api_frag.glsl"

    layout (location = 0) in vec3 in_color;

    void main()
    {
      WriteFragment(in_color);
    }