After few minutes I came up with very simple b/w Bayer Ordered dithering. I am quite sure someone has done it before me, but it was a nice exercise for me.
//Bayer Ordered dithering
uniform sampler2D bgl_RenderedTexture;
void main()
{
vec3 color = texture2D(bgl_RenderedTexture, gl_TexCoord[0].xy).rgb;
vec3 luminosity = vec3(0.30, 0.59, 0.11);
float lum = dot(luminosity, color);
float v = gl_FragCoord.s;
float h = gl_FragCoord.t;
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
if (lum < 0.9)
{
gl_FragColor.rgb *= round((fract(v/2))+(fract(h/2)));
}
if (lum < 0.75)
{
gl_FragColor.rgb *= round((fract(v+v/2))+(fract(h+h/2)));
}
if (lum < 0.5)
{
gl_FragColor.rgb *= round((fract(v+v+v/2))+(fract(h+h/2)));
}
if (lum < 0.25)
{
gl_FragColor.rgb *= round((fract(v+v/2))+(fract(h+h+h/2)));
}
}
and I just found a color Ordered dithering shader here (4x4 Bayer Matrix):
http://www.assembla.com/code/MUL2010_OpenGLScenePostprocessing/subversion/nodes/MUL%20FBO/Shaders/dithering.frag?rev=83
// Ordered dithering aka Bayer matrix dithering
uniform sampler2D bgl_RenderedTexture;
float scale = 1.0;
float find_closest(int x, int y, float c0)
{
vec4 dither[4];
dither[0] = vec4( 1.0, 33.0, 9.0, 41.0);
dither[1] = vec4(49.0, 17.0, 57.0, 25.0);
dither[2] = vec4(13.0, 45.0, 5.0, 37.0);
dither[3] = vec4(61.0, 29.0, 53.0, 21.0);
float limit = 0.0;
if(x < 4)
{
limit = (dither[x][y]+1.0)/64.0;
}
if(c0 < limit)
{
return 0.0;
}else{
return 1.0;
}
}
void main(void)
{
vec4 lum = vec4(0.299, 0.587, 0.114, 0.0);
float grayscale = dot(texture2D(bgl_RenderedTexture, gl_TexCoord[0].xy), lum);
vec3 rgb = texture2D(bgl_RenderedTexture, gl_TexCoord[0].xy).rgb;
vec2 xy = gl_FragCoord.xy * scale;
int x = int(mod(xy.x, 4.0));
int y = int(mod(xy.y, 4.0));
vec3 finalRGB;
finalRGB.r = find_closest(x, y, rgb.r);
finalRGB.g = find_closest(x, y, rgb.g);
finalRGB.b = find_closest(x, y, rgb.b);
float final = find_closest(x, y, grayscale);
gl_FragColor = vec4(finalRGB, 1.0);
}
Comparison screenshots (click to see full size):
Without filter
B/W dithering
Color dithering
Hi Martinsh,
ReplyDeleteI wanted to test this effect with ATI and had to do some changes:
##################
//Bayer Ordered dithering
uniform sampler2D bgl_RenderedTexture;
void main()
{
vec3 color = texture2D(bgl_RenderedTexture, gl_TexCoord[0].xy).rgb;
vec3 luminosity = vec3(0.30, 0.59, 0.11);
float lum = dot(luminosity, color);
float v = gl_FragCoord.s;
float h = gl_FragCoord.t;
float value;
gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);
if (lum < 0.9)
{
value = float(int((fract(v/2.0))+(fract(h/2.0))));
gl_FragColor.rgb *= vec3(value, value, value);
}
if (lum < 0.75)
{
value = float(int((fract(v+v/2.0))+(fract(h+h/2.0))));
gl_FragColor.rgb *= vec3(value, value, value);
}
if (lum < 0.5)
{
value = float(int((fract(v+v+v/2.0))+(fract(h+h/2.0))));
gl_FragColor.rgb *= vec3(value, value, value);
}
if (lum < 0.25)
{
value = float(int((fract(v+v/2.0))+(fract(h+h+h/2.0))));
gl_FragColor.rgb *= vec3(value, value, value);
}
}
################
Cheers.
ooh yeah, you are right. Mine does not work on ATI cards..
ReplyDeleteYours seems to be working very nicely though :)