Skip to content

Commit 9dd02a5

Browse files
committed
dithering and drunken stupor
1 parent 72ddbb5 commit 9dd02a5

File tree

2 files changed

+98
-0
lines changed

2 files changed

+98
-0
lines changed

dither.glsl

+30
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Simple "dithering" effect
2+
// (c) moni-dz (https://github.com/moni-dz)
3+
// CC BY-NC-SA 4.0 (https://creativecommons.org/licenses/by-nc-sa/4.0/)
4+
5+
// Packed bayer pattern using bit manipulation
6+
const float bayerPattern[4] = float[4](
7+
0x0514, // Encoding 0,8,2,10
8+
0xC4E6, // Encoding 12,4,14,6
9+
0x3B19, // Encoding 3,11,1,9
10+
0xF7D5 // Encoding 15,7,13,5
11+
);
12+
13+
float getBayerFromPacked(int x, int y) {
14+
int idx = (x & 3) + ((y & 3) << 2);
15+
return float((int(bayerPattern[y & 3]) >> ((x & 3) << 2)) & 0xF) * (1.0 / 16.0);
16+
}
17+
18+
#define LEVELS 2.0 // Available color steps per channel
19+
#define INV_LEVELS (1.0 / LEVELS)
20+
21+
void mainImage(out vec4 fragColor, in vec2 fragCoord)
22+
{
23+
vec2 uv = fragCoord * (1.0 / iResolution.xy);
24+
vec3 color = texture(iChannel0, uv).rgb;
25+
26+
float threshold = getBayerFromPacked(int(fragCoord.x), int(fragCoord.y));
27+
vec3 dithered = floor(color * LEVELS + threshold) * INV_LEVELS;
28+
29+
fragColor = vec4(dithered, 1.0);
30+
}

drunkard.glsl

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
// Drunken stupor effect using fractal Brownian motion and Perlin noise
2+
// (c) moni-dz (https://github.com/moni-dz)
3+
// CC BY-NC-SA 4.0 (https://creativecommons.org/licenses/by-nc-sa/4.0/)
4+
5+
vec2 hash2(vec2 p) {
6+
uvec2 q = uvec2(floatBitsToUint(p.x), floatBitsToUint(p.y));
7+
q = (q * uvec2(1597334673U, 3812015801U)) ^ (q.yx * uvec2(2798796415U, 1979697793U));
8+
return vec2(q) * (1.0/float(0xffffffffU)) * 2.0 - 1.0;
9+
}
10+
11+
float perlin2d(vec2 p) {
12+
vec2 i = floor(p);
13+
vec2 f = fract(p);
14+
vec2 u = f*f*(3.0-2.0*f);
15+
16+
return mix(mix(dot(hash2(i + vec2(0.0,0.0)), f - vec2(0.0,0.0)),
17+
dot(hash2(i + vec2(1.0,0.0)), f - vec2(1.0,0.0)), u.x),
18+
mix(dot(hash2(i + vec2(0.0,1.0)), f - vec2(0.0,1.0)),
19+
dot(hash2(i + vec2(1.0,1.0)), f - vec2(1.0,1.0)), u.x), u.y);
20+
}
21+
22+
#define OCTAVES 10 // How many passes of fractal Brownian motion to perform
23+
#define GAIN 0.5 // How much should each pixel move
24+
#define LACUNARITY 2.0 // How fast should each ripple be per pass
25+
26+
float fbm(vec2 p) {
27+
float sum = 0.0;
28+
float amp = 0.5;
29+
float freq = 1.0;
30+
31+
for(int i = 0; i < OCTAVES; i++) {
32+
sum += amp * perlin2d(p * freq);
33+
freq *= LACUNARITY;
34+
amp *= GAIN;
35+
}
36+
37+
return sum;
38+
}
39+
40+
41+
#define NOISE_SCALE 1.0 // How distorted the image you want to be
42+
#define NOISE_INTENSITY 0.05 // How strong the noise effect is
43+
#define ABERRATION true // Chromatic aberration
44+
#define ABERRATION_DELTA 0.1 // How strong the chromatic aberration effect is
45+
#define ANIMATE true
46+
#define SPEED 0.4 // Animation speed
47+
48+
void mainImage(out vec4 fragColor, in vec2 fragCoord)
49+
{
50+
vec2 uv = fragCoord/iResolution.xy;
51+
float time = ANIMATE ? iTime * SPEED : 0.0;
52+
53+
vec2 noisePos = uv * NOISE_SCALE + vec2(time);
54+
float noise = fbm(noisePos) * NOISE_INTENSITY;
55+
56+
vec3 col;
57+
58+
if (ABERRATION) {
59+
col.r = texture(iChannel0, uv + vec2(noise * (1.0 + ABERRATION_DELTA))).r;
60+
col.g = texture(iChannel0, uv + vec2(noise)).g;
61+
col.b = texture(iChannel0, uv + vec2(noise * (1.0 - ABERRATION_DELTA))).b;
62+
} else {
63+
vec2 distortedUV = uv + vec2(noise);
64+
col = texture(iChannel0, distortedUV).rgb;
65+
}
66+
67+
fragColor = vec4(col, 1.0);
68+
}

0 commit comments

Comments
 (0)