Wiki

Clone wiki

Core / CreateBasicShader

Back to Beyond the Codea in-app reference


Create a new basic shader

Introduction

In the Shader Lab (beta), in the 'Documents' Shader Pack, is an option to 'Create New Shader'. Tap the flask icon to create a new basic shader. You will be prompted to enter a name for the new shader. Once created, the shader can be edited.

Like all shaders, the basic shader has two parts: a vertex shader and a fragment shader. In the Shader Lab, the shader also has a 'Bindings' tab, which allows expressions in Lua to be bound to each of the uniform variables (see below) used in the shaders. The 'Bindings' feature allows the function of the shader to be previewed in the Shader Lab itself.

Shaders are not written in the Lua programming language, but in a different language called OpenGL ES Shading Language (or GLSL ES or ESSL, for short).

Basic vertex shader

All drawing in Codea is done by rendering triangles in three-dimensional space on to the two-dimensional space representing the Viewer. Each triangle has three corners (or vertices). As well as its position in three-dimensional space, each corner (or vertex) can have data associated with it, such as a colour or a uv co-ordinate (for a rectangular texture image). A vertex shader can manipulate (in its main() function) that per-vertex data and output it for use in the accompanying fragment shader.

Per-vertex data input to the vertex shader is provided as 'attribute' variables. As well as attributes, a vertex shader can take as an input data that is the same for all vertices, in the form of 'uniform' variables.

The main() function in the basic vertex shader is:

void main()
{
    ...
    vColor = color;
    vTexCoord = vec2(texCoord.x, 1.0 - texCoord.y); // Bug in Codea version 1.5.1
    ...
    gl_Position = modelViewProjection * position;
}

gl_Position is a variable that is intended for outputting the vertex position in homogenous co-ordinates (that is, as a vec4 value). All vertex shaders must write a value into that variable. Here, the modelViewProjection 4x4 matrix (see below) is applied to the vertex's position.

vColor and vTexCoord are 'varying' variables that allow per-vertex data to be passed from the vertex shader on to the accompanying fragment shader. Here, vColor passes on the color (without any manipulation) and vTexCoord passes on the texCoord (but, in Codea version 1.5.1, flips the v co-ordinate about a horizontal axis). The 'varying' variables are declared as follows:

varying lowp vec4 vColor;
varying highp vec2 vTexCoord;

Colours are represented by vec4 data: (red, green, blue, alpha). The values of each channel can run from 0.0 to 1.0.

The 'precision' of a variable can be specified. Here vColour has a low precision lowp and vTexCoord has a high precision highp.

The basic vertex shader has one uniform variable and three attribute variables. The values of all these variables are supplied automatically by Codea when the shader is used with a mesh.

uniform mat4 modelViewProjection; // the current model matrix * view matrix * projection matrix
attribute vec4 position;          // the vertex position in the mesh
attribute vec4 color;             // the vertex colour in the mesh  
attribute vec2 texCoord;          // the vertex uv co-ordinate in the mesh

The position has type vec4 because points in three-dimensional space are represented by homogenous co-ordinates: (x, y, z, w). The 4x4 matrix modelViewProjection has type mat4.

Basic fragment shader

A fragment shader outputs (in its own main() function) the colour of the fragment (pixel) that is being shaded. The inputs to a fragment shader are gl_Position and 'varying' variables from the accompanying vertex shader (interpolated, for fragments between vertices) and data that is the same for all fragments, in the form of 'uniform' variables.

The main() function in the basic fragment shader is very simple:

void main()
{
    ...
    lowp vec4 col = texture2D(texture, vTexCoord); //vColor is ignored in Codea version 1.5.1
    ...
    gl_FragColor = col;
}

gl_FragColor is a variable that is intended for outputting the color of the fragment. As with other variables representing colours, it is of type vec4: (red, green, blue, alpha), where each channel can run from 0.0 to 1.0.

Here, the variable col (defined within the scope of the main() function, is set to be the colour of the texture texture at location vTexCoord, using a texture lookup function that is built-in to GLSL ES (texture2D().

vTexCoord is the 'varying' variable that is being used to allow the accompanying vertex shader to pass per-vertex data to the fragment shader (see above). In Codea version 1.5.1, the other varying variable, vColor, is ignored.

The basic fragment shader has one uniform variable. The value of the variable is supplied automatically by Codea when the shader is used with a mesh.

uniform lowp sampler2D texture; //the current texture on the mesh

Here, the uniform variable texture is declared to be of type sampler2D. Variables of sampler types can only be declared as uniform variables or as parameters of functions. They represent textures and how they can be used is limited (see Section 4.1.7 'Samples' of the GLSL ES specification).

In fragment shaders, the precision of the float type (and other types based on float types, such as vec4) is not defined by default. However, it can be set using the precision statement:

precision highp float;

Updated