# Wiki

Clone wiki# Core / CheckerShader

## Checker Shader

### Introduction

'Checker' is an example shader provided in Codea's 'Patterns' Shaders Pack. Based on the location of a fragment on the Viewer, it produces a black-and-white checker-board effect.

### Vertex shader

The vertex shader does nothing other than set the `gl_Position`

of the vertex by applying the `modelViewProjection`

matrix to the `position`

attribute:

```
void main()
{
...
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. (See Section 7.1 'Vertex Shader Special Variables' of the GLSL ES specification.) Here, the `modelViewProjection`

4x4 matrix is applied to the vertex's `position`

. `modelViewProjection`

is a 'uniform' `mat4`

variable supplied automatically by Codea when the shader is used with a mesh. It is the current model matrix * view matrix * projection matrix. `position`

is a `vec4`

'attribute' variable, also supplied automatically by Codea from the mesh.

### Fragment shader

The fragment shader makes use of a 'uniform' variable `size`

, which represents the length of the sides of the squares in the check, in pixels. (The other 'uniform' variable, `resolution`

, is not used in the code and is redundant.)

The fragment shader sets `gl_FragColor`

to a `vec4`

constructed from `color`

(a `vec3`

) and an alpha (opacity) value of `0.9`

:

```
gl_FragColor = vec4(color, 0.90);
```

`color`

is constructed with all three components the same (`col`

:

```
color = vec3(col, col , col);
```

A more succinct syntax with the same effect is (see Section 5.4.2 'Vector and Matrix Constructors' of the GLSL ES specification):

```
color = vec3(col);
```

`color`

is declared and initialised as:

```
vec3 color = vec3(0.0);
```

The initialisation is redundant because another value is always assigned to the variable.

`col`

is set to `0.0`

or `1.0`

, depending on the components of `gl_FragCoord`

. Those components are initially reduced in scale by `size`

and rounded down to integer values:

```
vec2 position = (gl_FragCoord.xy);
...
float xpos = floor(position.x/size);
float ypos = floor(position.y/size);
```

As `gl_FragCoord`

is itself a `vec2`

value this could be rewritten more succinctly as:

```
float xpos = floor(gl_FragCoord.x / size);
float ypos = floor(gl_FragCoord.y / size);
```

`col`

is then calculated as:

```
float col = mod(xpos, 2.);
if (mod(ypos, 2.) > 0.)
if (col > 0.)
col = 0.;
else
col = 1.;
```

If `xpos`

(an integer) is even, then `mod(xpos, 2.0)`

is `0.0`

. Otherwise the expression is `1.0`

.

If `ypos`

(also an integer) is odd (and `mod(ypos, 2.0)`

is `1.0`

and greater than `0.0`

) then the value of `col`

is swapped (`0.0`

for `1.0`

and vice versa).

The same result can be acheived by:

```
float col = mod(xpos + mod(ypos, 2.0), 2.0);
```

In summary, an equivalent fragment shader is:

```
precision highp float;
uniform float size;
void main()
{
float xpos = floor(gl_FragCoord.x / size);
float ypos = floor(gl_FragCoord.y / size);
float col = mod(xpos + mod(ypos, 2.0), 2.0);
gl_FragColor = vec4(vec3(col), 0.90);
}
```

### Example of use

The code below is a simple example of the use of the shader:

```
function setup()
x = WIDTH / 2
y = HEIGHT / 2
a = 0
xm = 5
ym = 7
am = 3
myMesh = mesh()
myMesh:addRect(0, 0, 200, 200)
myMesh.shader = shader("Patterns:Checker")
parameter.integer("size", 20, 100, 50)
end
function draw()
background(255, 255, 0)
x = x + xm
y = y + ym
a = (a + am) % 360
if x < 0 then
x = -x
xm = -xm
end
if x > WIDTH then
x = 2 * WIDTH - x
xm = -xm
end
if y < 0 then
y = -y
ym = -ym
end
if y > HEIGHT then
y = 2 * HEIGHT - y
ym = -ym
end
translate(x, y)
rotate(a)
myMesh.shader.size = size
myMesh:draw()
end
```

Updated