Description

Pixelization is one of the simplest effects to implement. The main idea behind this effect is to divide the screen into squares of arbitrary size and then for each of these squares, sample a single color from the source image.

Taking this one step further, it’s possible to use different shapes to subdivide the screen space (eg. circles), achieving a more complex visual feel.

Samples

Below you can see examples of the effect implemented in shadertoy.

Simple pixelization

#define LUM vec3(.2126, .7152, .0722)
#define CHROMA_KEY
#define CHROMA_BIAS (0.13)
#define SCALE       (1.00)
#define BGCOLOR     vec3(0.03, 0.1, 0.2)

void mainImage(out vec4 c, vec2 p)
{
    float s = (SCALE * (iResolution.x / 6e1));
    c = texture(iChannel0, floor((p + .5) / s) * s / iResolution.xy);
    #ifdef CHROMA_KEY
    float lum = dot(LUM, c.rgb); // luminance
    if (lum > max(c.r, c.b) + CHROMA_BIAS) c = vec4(BGCOLOR,1);
    #endif /* CHROMA_KEY */
}

Dot-matrix effect

#define LUM vec3(.2126, .7152, .0722)
#define CHROMA_KEY
#define CHROMA_BIAS (00.13)
#define BGCOLOR     vec3(0.03, 0.1, 0.2)
#define GRID_SIZE   (35.0)
#define BIAS        (10.0)
#define SCALE       (32.0)

void mainImage(out vec4 color, in vec2 fragc)
{
    // Aspect corrected grid size.
    vec2  gridsz = GRID_SIZE * vec2(iResolution.x/iResolution.y, 1);
    // Grid coordinates with half a unit offset to sample
    // the center of the cell.
	vec2  pc  = fragc.xy / iResolution.xy * gridsz;
    vec2  cl  = floor(pc)+0.5;
    vec3  col = texture(iChannel0, cl / gridsz).rgb;

    // Calculate the sample's distance from the cell center.
    float dst = pow(1. - length(pc - cl), BIAS) * SCALE;
    float lum = dot(LUM, col.rgb); // luminance

    #ifdef CHROMA_KEY
    if (lum > max(col.r, col.b) + CHROMA_BIAS) col = BGCOLOR;
    #endif /* CHROMA_KEY */

    color = vec4(mix(BGCOLOR, col, min(1., dst*lum)), 1);
}