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 :)