I made a shader that produces a motion blur effect. It reminds me of handheld consoles’ LCD screens with their slow response times (specifically, GBA):
<?xml version="1.0" encoding="UTF-8"?>
<!--
Motion Blur
Author: hunterk
This program is free software; you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2 of the License, or (at your option)
any later version.
-->
<shader language="GLSL" style="GLES2">
<vertex><![CDATA[
#version 120
uniform mat4 rubyMVPMatrix;
attribute vec2 rubyVertexCoord;
attribute vec2 rubyTexCoord;
varying vec2 tex_coord;
void main()
{
gl_Position = rubyMVPMatrix * vec4(rubyVertexCoord, 0.0, 1.0);
tex_coord = rubyTexCoord;
}
]]></vertex>
<fragment><![CDATA[
uniform sampler2D rubyTexture;
uniform sampler2D rubyPrev6Texture;
varying vec2 tex_coord;
void main()
{
vec4 current = texture2D(rubyTexture, tex_coord);
vec4 prev = texture2D(rubyPrev6Texture, tex_coord);
gl_FragColor = (current + prev) / 2.0;
}
]]></fragment>
<vertex><![CDATA[
#version 120
uniform mat4 rubyMVPMatrix;
attribute vec2 rubyVertexCoord;
attribute vec2 rubyTexCoord;
varying vec2 tex_coord;
void main()
{
gl_Position = rubyMVPMatrix * vec4(rubyVertexCoord, 0.0, 1.0);
tex_coord = rubyTexCoord;
}
]]></vertex>
<fragment><![CDATA[
uniform sampler2D rubyTexture;
uniform sampler2D rubyPrev5Texture;
varying vec2 tex_coord;
void main()
{
vec4 current = texture2D(rubyTexture, tex_coord);
vec4 prev = texture2D(rubyPrev5Texture, tex_coord);
gl_FragColor = (current + prev) / 2.0;
}
]]></fragment>
<vertex><![CDATA[
#version 120
uniform mat4 rubyMVPMatrix;
attribute vec2 rubyVertexCoord;
attribute vec2 rubyTexCoord;
varying vec2 tex_coord;
void main()
{
gl_Position = rubyMVPMatrix * vec4(rubyVertexCoord, 0.0, 1.0);
tex_coord = rubyTexCoord;
}
]]></vertex>
<fragment><![CDATA[
uniform sampler2D rubyTexture;
uniform sampler2D rubyPrev4Texture;
varying vec2 tex_coord;
void main()
{
vec4 current = texture2D(rubyTexture, tex_coord);
vec4 prev = texture2D(rubyPrev4Texture, tex_coord);
gl_FragColor = (current + prev) / 2.0;
}
]]></fragment>
<vertex><![CDATA[
#version 120
uniform mat4 rubyMVPMatrix;
attribute vec2 rubyVertexCoord;
attribute vec2 rubyTexCoord;
varying vec2 tex_coord;
void main()
{
gl_Position = rubyMVPMatrix * vec4(rubyVertexCoord, 0.0, 1.0);
tex_coord = rubyTexCoord;
}
]]></vertex>
<fragment><![CDATA[
uniform sampler2D rubyTexture;
uniform sampler2D rubyPrev3Texture;
varying vec2 tex_coord;
void main()
{
vec4 current = texture2D(rubyTexture, tex_coord);
vec4 prev = texture2D(rubyPrev3Texture, tex_coord);
gl_FragColor = (current + prev) / 2.0;
}
]]></fragment>
<vertex><![CDATA[
#version 120
uniform mat4 rubyMVPMatrix;
attribute vec2 rubyVertexCoord;
attribute vec2 rubyTexCoord;
varying vec2 tex_coord;
void main()
{
gl_Position = rubyMVPMatrix * vec4(rubyVertexCoord, 0.0, 1.0);
tex_coord = rubyTexCoord;
}
]]></vertex>
<fragment><![CDATA[
uniform sampler2D rubyTexture;
uniform sampler2D rubyPrev2Texture;
varying vec2 tex_coord;
void main()
{
vec4 current = texture2D(rubyTexture, tex_coord);
vec4 prev = texture2D(rubyPrev2Texture, tex_coord);
gl_FragColor = (current + prev) / 2.0;
}
]]></fragment>
<vertex><![CDATA[
#version 120
uniform mat4 rubyMVPMatrix;
attribute vec2 rubyVertexCoord;
attribute vec2 rubyTexCoord;
varying vec2 tex_coord;
void main()
{
gl_Position = rubyMVPMatrix * vec4(rubyVertexCoord, 0.0, 1.0);
tex_coord = rubyTexCoord;
}
]]></vertex>
<fragment><![CDATA[
uniform sampler2D rubyTexture;
uniform sampler2D rubyPrev1Texture;
varying vec2 tex_coord;
void main()
{
vec4 current = texture2D(rubyTexture, tex_coord);
vec4 prev = texture2D(rubyPrev1Texture, tex_coord);
gl_FragColor = (current + prev) / 2.0;
}
]]></fragment>
<vertex><![CDATA[
#version 120
uniform mat4 rubyMVPMatrix;
attribute vec2 rubyVertexCoord;
attribute vec2 rubyTexCoord;
varying vec2 tex_coord;
void main()
{
gl_Position = rubyMVPMatrix * vec4(rubyVertexCoord, 0.0, 1.0);
tex_coord = rubyTexCoord;
}
]]></vertex>
<fragment><![CDATA[
uniform sampler2D rubyTexture;
uniform sampler2D rubyPrevTexture;
varying vec2 tex_coord;
void main()
{
vec4 current = texture2D(rubyTexture, tex_coord);
vec4 prev = texture2D(rubyPrevTexture, tex_coord);
gl_FragColor = (current + prev) / 2.0;
}
]]></fragment>
</shader>