Wiki
Clone wikiCore / RadialBlurShader
Radial Blur Shader
Introduction
'Radial Blur' is an example shader provided in Codea's 'Filters' Shaders Pack.
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 gl_FragColor
to a mix of two colours, tinted by multiplying the result by vColor
. The two colours are col
and sum
:
lowp vec4 col = texture2D(texture, vTexCoord);
...
gl_FragColor = mix(col, sum, t) * vColor;
sum
is calculated as the average of col
and ten colours sampled from the texture texture
:
mediump vec4 sum = col;
for (int i = 0; i < 10; i++)
{
sum += texture2D(texture, vTexCoord + dir * samples[i] * sampleDist);
}
sum *= 1.0 / 11.0;
dir
is a normalised vec2
from the vTexCoord
to the centre of the texture, at vec2(0.5, 0.5)
:
vec2 dir = 0.5 - vTexCoord.xy;
float dist = sqrt(dir.x * dir.x + dir.y * dir.y);
dir = dir / dist;
The ten points sampled are determined by the array samples[10]
.
The value of the mixing variable, t
, depends on the distance, dist
, clamped to the range 0.0
to 1.0
:
float t = dist * sampleStrength;
t = clamp(t, 0.0, 1.0);
Example of use
The code below is a simple example of the use of the shader:
function setup()
myMesh = mesh()
local img = readImage("Cargo Bot:Startup Screen")
local w, h = img.width, img.height
local s = math.min(WIDTH / w, HEIGHT / h)
myMesh:addRect(WIDTH / 2, HEIGHT / 2, w * s, h * s)
myMesh.texture = img
myShader = shader("Filters:Radial Blur")
parameter.boolean("isOn", true)
parameter.number("distance", 0.1, 3, 1,
function () isOn = true end)
parameter.number("strength", 0, 5, 2,
function () isOn = true end)
end
function draw()
background(0)
if isOn then
myMesh.shader = myShader
myMesh.shader.sampleDist = distance
myMesh.shader.sampleStrength = strength
else
myMesh.shader = nil
end
myMesh:draw()
end
Updated