User Tools

Site Tools


assets:shader

Shader

This article is about shader programs. Shaders are defined in ScriptedInfo files named shaders.dei.

Variables

Declaring a variable

Shader variables are uniforms, i.e, constants that can be changed at runtime without recompiling the shader.

Variables must be declared separately from their declaration in the shader source code. This lets Doomsday know which uniforms are intended to be externally modifiable. Also, Doomsday can initialize the variables to a specified initial values — useful when the shader is used in a context where the value of a particular variable is not specified.

The variable declaration looks like this:

variable uVariableName { value = 0.0 }

The given initial value may either be a single number or an array:

  • value = 0 → float
  • value <0, 0> → vec2
  • value <0, 0, 0> → vec3
  • value <0, 0, 0, 0> → vec4

The corresponding uniform in the shader source code would look like:

  uniform highp float uVariableName;

Built-in variables

The renderer provides built-in variables that can be used in any shader. To use one of these, the shader definition needs to declare the variable but omit any default value initializers. For example:

shader my_custom_shader {
  variable uMapTime {}
  ...

The GLSL source code also needs to declare a uniform with the exact same name, using the type from the table below.

Variable Type Description
uMapTime float Time in the current map, in seconds since the map was started. Does not increase while the game is paused.
uProjectionMatrix mat4 Transformation from 3D view space (eye at origin) to 2D screen space. The value of the uniform is updated once per frame/eye.
uViewMatrix mat4 Transforms from world space to view space. VGA aspect correction is included. The value of the uniform is updated once per frame/eye.

Model renderer uniforms

In addition to the variables above, the model renderer automatically provides a set of uniforms for model shaders. To use these, one simply needs to declare the variable in GLSL and use it (no declarations in Doomsday's shader definition are needed). The values are updated for each model that is rendered.

Uniform Type Description
uMvpMatrix mat4 The combined model-view-projection matrix.
uWorldMatrix mat4 Transforms from model space to world space.
uReflectionMatrix mat4 Rotation-only matrix for orienting a reflection cube map around the model.
uEyePos vec3 Model space eye position.
uAmbientLight vec3 Ambient light intensity (RGB).
uLightDirs vec3[4] Model space light directions.
uLightIntensities vec4[4] Light intensities (RGBA). A is the maximum of the R, G and B components.

Preprocessor definitions

A shader definition may specify a dictionary of macros that will apply to both vertex and fragment shaders in the shader program.

For example, the “model.skeletal.generic” shader defines the macros PREDEF_TRANSFORM_UV, PREDEF_TRANSFORM_EMISSION, and PREDEF_TRANSFORM_ALPHA. These can then be used to modify the texture UV, emission color, and surface opacity.

defines $= {'PREDEF_TRANSFORM_UV(uv)': 'uv = uv + vec2(0.5, 0.0)',
            'PREDEF_TRANSFORM_EMISSION(color)': 'color.r *= 2.0',
            'PREDEF_TRANSFORM_ALPHA(alpha)': ''}

This becomes particularly useful when combined with custom GLSL functions. Additional functions can be included as separate source files. Below is an example of using Doomsday Script to modify an inherited shader.

shader model.thing.misc3.uvscroll {
    inherits: model.skeletal.unlit.diffuse
    script {
        self.include.fragment += ['uvscroll.glsl']
        self.defines['PREDEF_TRANSFORM_UV(uv)'] = 'uv = scrolledUV(uv, uMapTime)'
    }
}

Example

Below is an example that demonstrates the use of a shader definition:

  • Declaring variables and their initial values.
  • Defining which texture maps are expected to be present, and therefore are available in the shader via attributes.
  • Including GLSL source files.
  • The shader source code.
shader "example" {
    variable uAlphaLimit { value = 0 }
    variable uAlpha      { value = 1.0 }
    variable uColor      { value <1, 1, 1> }
    variable uOffsetUV   { value <0, 0> }
 
    # Mapping when used with ModelDrawable.
    textureMapping <diffuse, normals>
 
    include.vertex <include/skeletal.glsl>
    vertex = "/* put GLSL source code here */"
 
    include.fragment <include/texture.glsl>
    fragment = "
        uniform highp float uAlphaLimit;
        uniform highp float uAlpha;
        uniform highp vec3 uColor;       // diffuse color multiplier
        uniform highp vec2 uOffsetUV;
 
        /* put GLSL source code here */"     
}         
assets/shader.txt · Last modified: 2017-08-26 16:58 by skyjake