Wiki
Clone wikiCore / BlurShader
Blur Shader
Introduction
'Blur' is an example shader provided in Codea's 'Filters' Shaders Pack. It performs a box blur on the texture associated with the mesh to which the shader is applied.
Vertex shader
The vertex shader simply passes the 'attribute' variables color
and texCoord
on to the accompanying fragment shader as 'varying' variables vColor
and vTexCoord
:
void main()
{
...
vColor = color;
vTexCoord = texCoord;
...
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 sets the gl_FragColor
in main()
as the product
of three factors, vColor
(the 'varying' passed on from the vertex
shader), conWeight
(a 'uniform' float
variable) and color
(which is calculated):
gl_FragColor = color * conWeight * vColor;
color
is calculated as the sum of the colours of nine points sampled from
the 'uniform' texture texture
(of type sampler2D
:
vec4 color = vec4(0.0);
...
for (int i = 0; i < 9; i++)
{
color += texture2D(texture, current);
current.x += conPixel.x;
if (i == 2 || i == 5) {
current.x = start.x;
current.y += conPixel.y;
}
}
The variable current
holds the point being sampled. The starting point (start
) is offset from vTexCoord
by
-1.5 * conPixel
. Consequently, the nine points sampled are (in units of
conPixel.x
and conPixel.y
):
i | point | Comment |
---|---|---|
0 | (-1.5, -1.5) | start |
1 | (-0.5, -1.5) | Increase current.x |
2 | ( 0.5, -1.5) | Increase current.x |
3 | (-1.5, -0.5) | Reset current.x and increase current.y |
4 | (-0.5, -0.5) | Increase current.x |
5 | ( 0.5, -0.5) | Increase current.x |
6 | (-1.5, 0.5) | Reset current.x and increase current.y |
7 | (-0.5, 0.5) | Increase current.x |
8 | ( 0.5, 0.5) | Increase current.x |
Example of use
The code below is a simple example of the use of the shader:
function setup()
local img = readImage("Cargo Bot:Codea Logo")
w, h = img.width, img.height
local aspect = h / w
local imgDim = math.min(w, h)
local viewerDim = math.min(WIDTH, HEIGHT / aspect)
myMesh = mesh()
myMesh:addRect(WIDTH / 2, HEIGHT / 2, viewerDim, viewerDim * aspect)
myMesh.shader = shader("Filters:Blur")
myMesh.texture = img
parameter.boolean("isSmooth", true, onChangeA)
parameter.boolean("isBlur", true, onChangeB)
myMesh.shader.conWeight = 1 / 9
end
function onChangeA()
if isSmooth then
smooth()
else
noSmooth()
end
end
function onChangeB()
if isBlur then
myMesh.shader.conPixel = vec2(1/w, 1/h)
else
myMesh.shader.conPixel = vec2()
end
end
function draw()
background(255, 255, 0)
myMesh:draw()
end
Updated