March 10, 2011

GLSL 8x8 Bayer matrix dithering

and here is 8x8 Bayer matrix dithering

based on this paper: http://www.efg2.com/Lab/Library/ImageProcessing/DHALF.TXT


// Ordered dithering aka Bayer matrix dithering

uniform sampler2D bgl_RenderedTexture;
float Scale = 1.0;

float find_closest(int x, int y, float c0)
{

int dither[8][8] = {
{ 0, 32, 8, 40, 2, 34, 10, 42}, /* 8x8 Bayer ordered dithering */
{48, 16, 56, 24, 50, 18, 58, 26}, /* pattern. Each input pixel */
{12, 44, 4, 36, 14, 46, 6, 38}, /* is scaled to the 0..63 range */
{60, 28, 52, 20, 62, 30, 54, 22}, /* before looking in this table */
{ 3, 35, 11, 43, 1, 33, 9, 41}, /* to determine the action. */
{51, 19, 59, 27, 49, 17, 57, 25},
{15, 47, 7, 39, 13, 45, 5, 37},
{63, 31, 55, 23, 61, 29, 53, 21} };

float limit = 0.0;
if(x < 8)
{
limit = (dither[x][y]+1)/64.0;
}


if(c0 < limit)
return 0.0;
return 1.0;
}

void main(void)
{
vec4 lum = vec4(0.299, 0.587, 0.114, 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, 8));
int y = int(mod(xy.y, 8));

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

original gradient


8x8 dither


4x4 dither


2x2 dither

March 9, 2011

GLSL dithering

looking at previous post (crosshatch), it inspired me to take a deeper look into dithering algorithms. http://en.wikipedia.org/wiki/Dithering
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

crosshatch shader

found a nice crosshatch shader
http://learningwebgl.com/blog/?p=2858




//Source
//http://learningwebgl.com/blog/?p=2858

uniform sampler2D bgl_RenderedTexture;

void main()
{
float lum = length(texture2D(bgl_RenderedTexture, gl_TexCoord[0].xy).rgb);

gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);

if (lum < 1.00) {
if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
}

if (lum < 0.75) {
if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
}

if (lum < 0.50) {
if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
}

if (lum < 0.3) {
if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {
gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);
}
}
}

hello world!

There is forming a real mess on my hard drive, so I am gonna use this blog as a sorted archive of game development stuff.

hopefully..