- Sign In
- Sign Up
Dithered Observations
This is a simple plasma retro piece created to study and observe color quantization, resolution constraining, and different types of dithering.
Created by marcogomez on Wed, 27 Oct 2021 10:23:54 GMT.
// ╔═════════════╦════════════════╗ // ║ Marco Gomez ║ https://mgz.me ║ // ╚═════════════╩════════════════╝ precision highp float; uniform sampler2D prgm2Texture; uniform vec2 resolution; void main(void) { vec2 uv = gl_FragCoord.xy / resolution.xy; vec4 tex = texture2D(prgm2Texture, uv); gl_FragColor = tex; }
// ╔═════════════╦════════════════╗ // ║ Marco Gomez ║ https://mgz.me ║ // ╚═════════════╩════════════════╝ precision highp float; uniform vec2 resolution; uniform vec2 mouselerp; uniform float time; uniform float fftNormalized; const float PI = acos(-1.0); const float TAU = PI * 2.0; void main(void) { float t = time * 0.2; vec2 res = resolution.xy; vec2 coord = gl_FragCoord.xy; float ar = resolution.x / resolution.y; vec2 mCoord = vec2(mouselerp.x * res.x / ar, mouselerp.y * res.y / ar); coord -= mCoord; float scale = resolution.x / 1.25; vec2 center = vec2( (res.x / 2.0) + sin(t) * (res.x / 1.5), (res.y / 2.0) + cos(t) * (res.y / 1.5) ); float dist = length(coord.xy - center); float c = ( (sin(dist / (scale / 7.6) + sin(t * 1.1) * 5.0) + 1.25) + (sin(dist / (scale / 11.5) - sin(t * 1.1) * 6.0) + 1.25) ); float x = ( (sin(coord.x / (scale / 6.5) + sin(t * 1.1) * 4.5) + 1.25) + (sin(coord.x / (scale / 9.2) - sin(t * 1.1) * 5.5) + 1.25) + fftNormalized + (mouselerp.x * TAU) ); float y = ( (sin(coord.y / (scale / 6.8) + sin(t * 1.1) * 4.75) + 1.25) + (sin(coord.y / (scale / 12.5) - sin(t * 1.1) * 5.75) + 1.25) + fftNormalized + (mouselerp.y * TAU) ); float acc = c + x + y / 3.0; vec3 color = vec3( (cos(PI * acc / 4.0 + t * 3.0) + 1.0) / 2.0, (sin(PI * acc / 3.5 + t * 3.0) + 1.0) / 2.5, (sin(PI * acc / 2.0 + t * 3.0) + 2.0) / 8.0 ); gl_FragColor = vec4(clamp(color, 0.0, 1.0), 1.0); }
// ╔═════════════╦════════════════╗ // ║ Marco Gomez ║ https://mgz.me ║ // ╚═════════════╩════════════════╝ precision highp float; uniform sampler2D blueNoiseTexture; uniform sampler2D ditherTexture; uniform sampler2D prgm1Texture; uniform vec2 resolution; uniform float time; #define BITS 5 #define PIXEL_SIZE 8 #define ENCODE_IN_SRGB 1 #define DITHER 1 #define DITHER_TYPE 1 const float PI = acos(-1.0); const float TAU = PI * 2.0; const float bgWaveSpeed = 1.0; const float xDistMag = 0.025; const float yDistMag = 0.025; const float xSineCycles = TAU; const float ySineCycles = TAU; float uniformNoise(vec2 n) { return fract(sin(dot(n, vec2(12.9898, 78.233))) * 43758.5453); } float triangleNoise(vec2 n) { vec2 p = fract(n * vec2(5.3987, 5.4421)); p += dot(p.yx, p.xy + vec2(21.5351, 14.3137)); float xy = p.x * p.y; float noise = (fract(xy * 95.4307) + fract(xy * 75.04961) - 1.0); return noise; } float interleavedGradientNoise(vec2 n) { float f = 0.06711056 * n.x + 0.00583715 * n.y; return fract(52.9829189 * fract(f)); } float triangleRemap(float n) { float origin = n * 2.0 - 1.0; float v = origin / sqrt(abs(origin)); v = max(-1.0, v); v -= sign(origin); return v; } vec3 triangleRemap(const vec3 n) { return vec3( triangleRemap(n.x), triangleRemap(n.y), triangleRemap(n.z) ); } vec3 HSVToSRGB(float h, float s, float v) { return vec3( v * (1.0 - s + s * clamp(abs(fract(h + 1.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0)), v * (1.0 - s + s * clamp(abs(fract(h + 2.0 / 3.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0)), v * (1.0 - s + s * clamp(abs(fract(h + 1.0 / 3.0) * 6.0 - 3.0) - 1.0, 0.0, 1.0)) ); } vec3 SRGBToRGB(vec3 v) { for (int i = 0; i < 3; ++i) { if (v[i] <= 0.04045) { v[i] /= 12.92; } else { v[i] = pow((v[i] + 0.055) / (1.055), 2.4); } } return v; } vec3 RGBToSRGB(vec3 v) { for (int i = 0; i < 3; ++i) { if (v[i] <= 0.0031308) { v[i] *= 12.92; } else { v[i] = (1.055) * pow(v[i], 1.0/2.4) - 0.055; } } return v; } float precisionFromBits(float b) { return 1.0 / (pow(abs(2.0), b) - 1.0); } vec3 roundToPrecision(vec3 v, float p) { return clamp(p * floor((v / p) + 0.5), vec3(0.0), vec3(1.0)); } vec3 dither(vec3 v, vec2 fragCoord, float p, int type) { vec2 coord = fragCoord.xy / 16.0; if (type == 1) { return v + (texture2D(blueNoiseTexture, mod(fragCoord, 1024.0) / 1024.0).rgb - 0.5) * (p * 1.5); } else if (type == 2) { float n = texture2D(ditherTexture, fract(coord)).r; n = n - 0.5; return v + vec3(n / 4.0); } else if (type == 3) { float noise = uniformNoise((coord)); noise = noise - 0.5; return v + vec3(noise / 8.0); } else if (type == 4) { vec3 noise = vec3(triangleNoise(coord) / 8.0); return v + noise; } else if (type == 5) { float noise = interleavedGradientNoise(coord * 4.0); noise = noise - 0.5; return v + vec3(noise / 4.0); } else if (type == 6) { vec3 noise = vec3(dot(vec2(171.0, 231.0), coord / 1.3)); noise = fract(noise / vec3(103.0, 71.0, 97.0)); noise = triangleRemap(noise); return v + vec3(noise / 8.0); } else if (type == 7) { float gridPosition = fract(dot(fragCoord.xy - vec2(0.5), vec2(1.0 / 16.0, 10.0 / 36.0) + 0.25)); float ditherShift = 0.25 * p; vec3 ditherShiftRGB = vec3(ditherShift, -ditherShift, ditherShift); ditherShiftRGB = mix(2.0 * ditherShiftRGB, -2.0 * ditherShiftRGB, gridPosition); return v + ditherShiftRGB + p * 0.5; } } void main(void) { vec2 fragCoord = (floor((gl_FragCoord.xy - 0.5) / float(PIXEL_SIZE)) + 0.5) * float(PIXEL_SIZE); vec2 uv = fragCoord.xy / resolution.xy; float minRes = min(resolution.x, resolution.y); vec2 fc = gl_FragCoord.xy / minRes; float wt = time * bgWaveSpeed; float xAngle = wt + fc.y * ySineCycles; float yAngle = wt + fc.x * xSineCycles; bool bxHalf, byHalf; vec2 distortOffset = vec2(sin(xAngle), sin(yAngle)) * vec2(xDistMag, yDistMag); vec3 tex = texture2D(prgm1Texture, uv + distortOffset).rgb; float p = precisionFromBits(float(BITS)); #if ENCODE_IN_SRGB == 0 tex = SRGBToRGB(tex); #endif #if DITHER tex = dither(tex, fragCoord, p, DITHER_TYPE); #endif tex = roundToPrecision(tex, p); #if ENCODE_IN_SRGB == 0 tex = RGBToSRGB(tex); #endif gl_FragColor = vec4(tex, 1.0); }
xxxxxxxxxx
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
uniform sampler2D prgm2Texture;
uniform vec2 resolution;
void main(void) {
vec2 uv = gl_FragCoord.xy / resolution.xy;
vec4 tex = texture2D(prgm2Texture, uv);
gl_FragColor = tex;
}
86 fps 16ms
00:00:00.42
0.00