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 HIRO shader API usable 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 including guards. When including a file, be careful that you did not already have the file 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. A similar applies to UBO bindings. Here, the notation UBIND_CUSTOM_n is used, where n is a binding index.

An example of use:

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

Transformations

The rendering system uses several transformation steps to obtain the final transformation.

_images/transformations.svg

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

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 is included only if enabled.

mat4 GetTransfView();

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

mat4 GetTransfProjection();

Returns full instance-model-view-projection transformation. Instance transformation is 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 a 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 a shadow cast on a specified position.

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

Writes fragment to deferred buffers, specifying a fragment’s position and normal vector 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 the color will appear unmodified in the final render.

Examples

Vertex Shader

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

An example of a very simple vertex shader:

 1#version 430
 2#include "api_vert.glsl"
 3
 4layout (location = 0) in vec3 in_position;
 5layout (location = ULOC_CUSTOM_0) uniform vec3 color;
 6
 7void main ()
 8{
 9  out_color = in_color;
10  gl_Position = GetTransfProjection() * vec4(in_position, 1.0);
11}

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#version 430
2#include "api_frag.glsl"
3
4layout (location = 0) in vec3 in_color;
5
6void main()
7{
8  WriteFragment(in_color);
9}