- Sign In
- Sign Up
The 16 Segment Display
This piece demonstrates an easy (but pricy to compile due to abuse of divergent branching) way to draw text emulating a 16 segment display.
Created by marcogomez on Fri, 30 Oct 2020 03:30:51 GMT.
// ╔═════════════╦════════════════╗ // ║ Marco Gomez ║ https://mgz.me ║ // ╚═════════════╩════════════════╝ precision highp float; uniform sampler2D prgm3Texture; uniform vec2 resolution; void main(void) { vec2 uv = gl_FragCoord.xy / resolution.xy; vec4 prgm3 = texture2D(prgm3Texture, uv); gl_FragColor = vec4(prgm3.xyz, 1.0); }
// ╔═════════════╦════════════════╗ // ║ Marco Gomez ║ https://mgz.me ║ // ╚═════════════╩════════════════╝ /* ╔════════════════════════════════════════════════════════════════════╗ ║ LET'S PLAY WITH 16 LINE SEGMENTS "DIGITAL DISPLAYS" ║ ╠════════════════════════════════════════════════════════════════════╣ ║The display is composed by 16 "line segments" that can be ON and OFF║ ║You can see a map below, showing the display 16 "positions" (bits) ║ ╠════════════════╦═══════════════════════════════════════════════════╣ ║ bits positions ║ Following the positions map on the left, you can ║ ║ ║ start thinking on how to compose the capital A. ║ ║ ┌──2──┬──1──┐ ║ Think on the bits from 0 to 15, and observe which ║ ║ │\ │ /│ ║ ones needs to be ON (1) and OFF (0), so... ║ ║ │ \ │ / │ ║ for the letter A we need the following positions ║ ║ 3 11 10 9 0 ║ on the left map to be ON (1): ║ ║ │ \ │ / │ ║ 0 1 2 3 4 7 8 12, and all other positions OFF (0) ║ ║ │ \│/ │ ║ ║ ║ ├─12──X──8──┤ ║ So, let's think about all the positions in order, ║ ║ │ /│\ │ ║ and remember that 1 is ON, and 0 is OFF ║ ║ │ / │ \ │ ║ ║ ║ 4 13 14 15 7 ║ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 ║ ║ │ / │ \ │ ║ | | | | | | | | | | | | | | | | ║ ║ │/ │ \│ ║ 1 1 1 1 1 0 0 1 1 0 0 0 1 0 0 0 ║ ║ └──5──┴──6──┘ ║ ║ ║ ║ bits: 1111100110001000 ║ ╠════════════════╣ reversed: 0001000110011111 ║ ║ ║ split: 0001 0001 1001 1111 ║ ║ BINARY TO HEX ║ group: 1 2 3 4 ║ ║ ║ ║ ║ DEC HEX BIN ║ So if you look at the quick reference table on ║ ║ 00 0 0000 ║ the left, you can convert our four 4-bits groups ║ ║ 01 1 0001 ║ to the HEX representation, as each HEX value can ║ ║ 02 2 0010 ║ represent 4 bits. So, in HEX, we have our letter ║ ║ 03 3 0011 ║ ║ ║ 04 4 0100 ║ GROUP BIN HEX ║ ║ 05 5 0101 ║ 1 0001 1 ║ ║ 06 6 0110 ║ 2 0001 1 ║ ║ 07 7 0111 ║ 3 1001 9 ║ ║ 08 8 1000 ║ 4 1111 F ║ ║ 09 9 1001 ║ ║ ║ 10 A 1010 ║ So, the letter A would be HEX: 0x119F ║ ║ 11 B 1011 ║ Easy right? Now you can draw some old-school ║ ║ 12 C 1100 ║ stuff ║ ║ 13 D 1101 ║ ║ ║ 14 E 1110 ║ ║ ║ 15 F 1111 ║ ║ ╚════════════════╩═══════════════════════════════════════════════════╝*/ #define A ddigit(0x119F); #define B ddigit(0x927E); #define C ddigit(0x007E); #define D ddigit(0x44E7); #define E ddigit(0x107E); #define F ddigit(0x101E); #define G ddigit(0x807E); #define H ddigit(0x1199); #define I ddigit(0x4466); #define J ddigit(0x4436); #define K ddigit(0x9218); #define L ddigit(0x0078); #define M ddigit(0x0A99); #define N ddigit(0x8899); #define O ddigit(0x00FF); #define P ddigit(0x111F); #define Q ddigit(0x80FF); #define R ddigit(0x911F); #define S ddigit(0x09E6); #define T ddigit(0x4406); #define U ddigit(0x00F9); #define V ddigit(0x2218); #define W ddigit(0xA099); #define X ddigit(0xAA00); #define Y ddigit(0x4A00); #define Z ddigit(0x2266); #define n0 ddigit(0x22FF); #define n1 ddigit(0x0281); #define n2 ddigit(0x1177); #define n3 ddigit(0x11E7); #define n4 ddigit(0x5508); #define n5 ddigit(0x11EE); #define n6 ddigit(0x11FE); #define n7 ddigit(0x2206); #define n8 ddigit(0x11FF); #define n9 ddigit(0x11EF); #define s_dot ddots(0); #define s_ddot ddots(1); #define s_minus ddigit(0x1100); #define s_plus ddigit(0x5500); #define s_greater ddigit(0x2800); #define s_less ddigit(0x8200); #define s_open ddigit(0x003C); #define s_close ddigit(0x00C3); #define s_sqrt ddigit(0x0C02); #define s_uline ddigit(0x0060); #define s_apos ddigit(0x0400); #define leftarrow ddigit(0x8300); #define s_slash ddigit(0x2200); #define _ chPos.x += chSpace.x; // blank #define nl chPos.x = chStart.x; chPos.y -= 2.0; #define EFFECT_LENGTH 6.0 precision highp float; uniform vec2 resolution; uniform vec2 mouse; uniform float time; uniform float fft; const int starsPerPlane = 30; const int planes = 4; const vec3 blue = vec3(0.00, 0.00, 0.99); const vec3 purple = vec3(0.70, 0.00, 0.90); const vec2 chSize = vec2(0.7, 0.5); // character size const vec2 chSpace = chSize + vec2(0.4, 0.6); // character distance vec2 chStart; vec2 chPos = vec2(0.0, 0.0); // character position vec3 chColor = vec3(0.6, 1.7, 0.8); // character color vec3 bgColor = vec3(0.0, 0.0, 0.0); // background color vec2 tuv; // current text uv position float drawSegment(vec2 p0, vec2 p1) { p0 *= chSize; p1 *= chSize; vec2 dir = normalize(p1 - p0); vec2 charPos = (tuv - chPos - p0) * mat2(dir.x, dir.y, -dir.y, dir.x); vec2 clampDist = clamp(charPos, vec2(0.0), vec2(distance(p0, p1), 0.0)); return 2.0 * distance(charPos, clampDist); } bool bit(int n, int b) { // return true if bit b of n is set ( not 0 ) return mod(floor(float(n) / exp2(floor(float(b)))), 2.0) != 0.0; } float d = 1.0; void ddots(int n) { float v = 1.0; if (n == 0) { v = min(v, drawSegment(vec2(-0.005, -1.000), vec2(0.000, -1.000))); } else if (n == 1) { v = min(v, drawSegment(vec2(0.005,-1.0), vec2(0.0, -1.0))); v = min(v, drawSegment(vec2(0.005, 0.0), vec2(0.0, 0.0))); } chPos.x += chSpace.x; d = min(d, v); } void ddigit(int n) { float v = 1.0; if (bit(n, 0)) { v = min(v, drawSegment(vec2( 0.500, 0.063), vec2( 0.500, 0.937))); } if (bit(n, 1)) { v = min(v, drawSegment(vec2( 0.438, 1.000), vec2( 0.063, 1.000))); } if (bit(n, 2)) { v = min(v, drawSegment(vec2(-0.063, 1.000), vec2(-0.438, 1.000))); } if (bit(n, 3)) { v = min(v, drawSegment(vec2(-0.500, 0.937), vec2(-0.500, 0.062))); } if (bit(n, 4)) { v = min(v, drawSegment(vec2(-0.500, -0.063), vec2(-0.500, -0.938))); } if (bit(n, 5)) { v = min(v, drawSegment(vec2(-0.438, -1.000), vec2(-0.063, -1.000))); } if (bit(n, 6)) { v = min(v, drawSegment(vec2( 0.063, -1.000), vec2( 0.438, -1.000))); } if (bit(n, 7)) { v = min(v, drawSegment(vec2( 0.500, -0.938), vec2( 0.500, -0.063))); } if (bit(n, 8)) { v = min(v, drawSegment(vec2( 0.063, 0.000), vec2( 0.438, -0.000))); } if (bit(n, 9)) { v = min(v, drawSegment(vec2( 0.063, 0.063), vec2( 0.438, 0.938))); } if (bit(n, 10)) { v = min(v, drawSegment(vec2( 0.000, 0.063), vec2( 0.000, 0.937))); } if (bit(n, 11)) { v = min(v, drawSegment(vec2(-0.063, 0.063), vec2(-0.438, 0.938))); } if (bit(n, 12)) { v = min(v, drawSegment(vec2(-0.438, 0.000), vec2(-0.063, -0.000))); } if (bit(n, 13)) { v = min(v, drawSegment(vec2(-0.063, -0.063), vec2(-0.438, -0.938))); } if (bit(n, 14)) { v = min(v, drawSegment(vec2( 0.000, -0.938), vec2( 0.000, -0.063))); } if (bit(n, 15)) { v = min(v, drawSegment(vec2( 0.063, -0.063), vec2( 0.438, -0.938))); } chPos.x += chSpace.x; d = min(d, v); } void showFloat(float value) { for (int ni = 4; ni > -3; ni--) { if (ni == -1) { s_dot; } // add dot float dd = (value / pow(10.0, float(ni))); dd = mod(floor(dd), 10.0); if (dd < 0.5) { n0 } else if (dd < 1.5) { n1 } else if (dd < 2.5) { n2 } else if (dd < 3.5) { n3 } else if (dd < 4.5) { n4 } else if (dd < 5.5) { n5 } else if (dd < 6.5) { n6 } else if (dd < 7.5) { n7 } else if (dd < 8.5) { n8 } else if (dd < 9.5) { n9 } } } void showInteger4Digits(int value) { float fv = float(value); for (int ni = 3; ni >= 0; ni--) { float dd = fv / pow(10.0, float(ni)); dd = mod(floor(dd), 10.0); if (dd < 0.5) { n0 } else if (dd < 1.5) { n1 } else if (dd < 2.5) { n2 } else if (dd < 3.5) { n3 } else if (dd < 4.5) { n4 } else if (dd < 5.5) { n5 } else if (dd < 6.5) { n6 } else if (dd < 7.5) { n7 } else if (dd < 8.5) { n8 } else if (dd < 9.5) { n9 } } } void showInteger(int value) { bool startDisplay = false; float fv = float( value ) / 10000.0; for (int ni = 5; ni > 0; ni--) { float dd = mod(floor(fv), 10.0); if ( dd > 1.0 ) { startDisplay = true; } if ( startDisplay ) { if (dd < 0.5) { n0 } else if (dd < 1.5) { n1 } else if (dd < 2.5) { n2 } else if (dd < 3.5) { n3 } else if (dd < 4.5) { n4 } else if (dd < 5.5) { n5 } else if (dd < 6.5) { n6 } else if (dd < 7.5) { n7 } else if (dd < 8.5) { n8 } else if (dd < 9.5) { n9 } fv = fv * 10.0; } } } vec3 hsv2rgbSmooth(vec3 c) { vec3 rgb = abs(mod(c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0; rgb = clamp(rgb, 0.0, 1.0); rgb = rgb * rgb * (3.0 - 2.0 * rgb); // cubic smoothing return c.z * mix(vec3(1.0), rgb, c.y); } float lineStep(float x0, float x1, float xn) { return (xn - x0) / (x1 - x0); } float dist(vec2 v0, vec2 v1) { v0 = abs(v0 - v1); return max(v0.x, v0.y); } vec2 rotate(vec2 uv, float a) { return vec2(uv.x * cos(a) - uv.y * sin(a), uv.x * sin(a) + uv.y * cos(a)); } float osc(float s, float e, float t, float ts) { return (e - s) / 2.0 + s + sin(t * ts) * (e - s) * 0.5; } vec2 curve(vec2 uv) { uv = (uv - 0.5) * 2.0; uv *= 1.1; uv.x *= 1.0 + pow( ( abs( uv.y ) / 5.0 ), 2.0 ); uv.y *= 1.0 + pow( ( abs( uv.x ) / 4.0 ), 2.0 ); uv = (uv / 2.0) + 0.5; uv = uv * 0.92 + 0.04; return uv; } float rand(float n) { return fract(sin(n) * 43758.5453123); } float rand (vec2 uv) { return fract(sin(dot(uv, vec2(12.4124, 48.4124))) * 48512.41241); } float noise (vec2 uv) { vec2 b = floor(uv); return mix( mix(rand(b), rand(b + vec2(1.0, 0.0)), 0.5), mix(rand(b + vec2(0.0, 1.0)), rand(b + vec2(1.0, 1.0)), 0.5), 0.5 ); } void main(void) { float ar = max(resolution.x, resolution.y) / min(resolution.x, resolution.y); tuv = (gl_FragCoord.xy / resolution.xy) * 2.0 - 1.0; chStart = vec2(tuv.x - 7.0 - chSpace.x, chSpace.y); // start position tuv.x *= ar; tuv *= 6.0; tuv.x += sin(time + tuv.y * 0.15) * 0.5; tuv.y += sin(time + tuv.x * 0.30) * 0.5; chPos = chStart + vec2(0.0, 0.0); // set start position chColor = hsv2rgbSmooth(vec3(time * 0.75 + tuv.x * 0.1, 0.6, 0.012)) * 2.0; {T H E _ C O D E _ T H E R A P Y} chColor = mix(chColor, vec3(0.0), 1.5 - (2.8 / d)); chColor *= clamp(0.1 / d, 0.0, 1.0); chColor = smoothstep(0.07, 0.9, chColor); vec2 suv = gl_FragCoord.xy / resolution.xy; const float speed = 42.0; const int layers = 12; float stars = 0.0; float fl, s; for (int layer = 0; layer < layers; layer++) { fl = float(layer); s = (500.0 - fl * 30.0); stars += step( 0.1, pow( abs(noise(mod(vec2(suv.x * s + time * speed - fl * 100.0, suv.y * s), resolution.x))), 21.0 ) ) * (fl / float(layers)); } vec4 starsColor = vec4(stars); vec4 finalColor = vec4(chColor + stars, 1.0); finalColor.xyz *= mod(gl_FragCoord.y, 3.0); gl_FragColor = finalColor; }
// ╔═════════════╦════════════════╗ // ║ Marco Gomez ║ https://mgz.me ║ // ╚═════════════╩════════════════╝ precision highp float; uniform sampler2D prgm1Texture; uniform vec2 resolution; uniform float time; uniform float fft; const float PI = acos(-1.0); const float TAU = PI * 2.0; const float h = 0.003; const float v = 0.009; const float g = 0.05; float stepm(float a, float b, float c) { return step(c, sin(time + a * cos(time * b))); } vec3 badVHS(vec2 uv, sampler2D tex) { float tmod = mod(time * 0.25, 3.0); float lookyMod = uv.y - tmod; float window = 1.0 / (1.0 + 20.0 * lookyMod * lookyMod); float lookyStep = stepm(4.0, 4.0, 0.3); uv.x = uv.x + sin(uv.y * 10.0 + time) / 100.0 * lookyStep * (1.0 + cos(time * 80.0)) * window * 0.25; float vShift = v * stepm(2.0, 3.0, 0.9) * (sin(time) * sin(time * 20.0) + (0.5 + 0.1 * sin(time * 200.0) * cos(time))); uv.y = mod(uv.y + vShift, 5.0); vec3 desatColor; float _r, _g, _b; float x = sin(0.3 * time + uv.y * 21.0) * sin(0.7 * time + uv.y * 29.0) * sin(0.3 + 0.33 * time + uv.y * 31.0) * h; _r = texture2D(tex, vec2(x + uv.x + 0.001, uv.y + 0.001)).x + 0.003; _g = texture2D(tex, vec2(x + uv.x + 0.000, uv.y - 0.002)).y + 0.003; _b = texture2D(tex, vec2(x + uv.x - 0.002, uv.y + 0.000)).z + 0.003; _r += 0.08 * texture2D(tex, 0.75 * vec2(x + 0.006, -0.007) + vec2(uv.x + 0.001, uv.y + 0.001)).x; _g += 0.05 * texture2D(tex, 0.75 * vec2(x + -0.005, -0.005) + vec2(uv.x + 0.000, uv.y - 0.002)).y; _b += 0.08 * texture2D(tex, 0.75 * vec2(x + -0.005, -0.003) + vec2(uv.x - 0.002, uv.y + 0.000)).z; float _luma = 0.3 * _r + 0.6 * _g + 0.1 * _b; float _desat = 0.3; desatColor = vec3( _r + _desat * (_luma - _r), _g + _desat * (_luma - _g), _b + _desat * (_luma - _b) ); desatColor = clamp(desatColor, 0.0, 1.0); return desatColor; } float oscillate(float s, float e, float t) { return (e - s) * 0.5 + s + sin(t) * (e - s) * 0.5; } float gaussian(float z, float u, float o) { return ( (1.0 / (o * sqrt(2.0 * 3.14159265359))) * (exp(-(((z - u) * (z - u)) / (2.0 * (o * o))))) ); } vec3 gaussgrain(float t) { vec2 ps = vec2(1.0) / resolution.xy; vec2 uv = gl_FragCoord.xy * ps; float seed = dot(uv, vec2(12.9898, 78.233)); float noise = fract(sin(seed) * 43758.5453123 + t); noise = gaussian(noise, 0.0, 0.5); return vec3(noise); } vec2 curve(vec2 uv) { uv = (uv - 0.5) * 2.0; uv *= 1.1; uv.x *= 1.0 + pow((abs(uv.y) / 5.0), 2.0); uv.y *= 1.0 + pow((abs(uv.x) / 4.0), 2.0); uv = (uv / 2.0) + 0.5; uv = uv * 0.92 + 0.04; return uv; } void main(void) { vec2 uv = gl_FragCoord.xy / resolution.xy; vec4 prgm1 = texture2D(prgm1Texture, uv); vec2 cuv = curve(uv); float frameScale = 29.97; float frameTime = floor(time * frameScale) / frameScale; vec3 grain = gaussgrain(frameTime * 2.0); vec3 vhsCol = badVHS(cuv, prgm1Texture) + (grain * grain) * g; float vig = (0.0 + 1.0 * 21.0 * cuv.x * cuv.y * (1.0 - cuv.x) * (1.0 - cuv.y)); vhsCol *= vec3(pow(abs(vig), 1.4)); float scans = clamp(0.35 + 0.35 * sin(3.5 * time + cuv.y * resolution.y * 1.5), 0.0, 1.0); float s = pow(scans, 1.33); vhsCol = vhsCol * vec3(1.4 + 1.7 * s); if (cuv.x < 0.0 || cuv.x > 1.0) { vhsCol *= 0.0; } if (cuv.y < 0.0 || cuv.y > 1.0) { vhsCol *= 0.0; } vhsCol *= 1.0 - 0.37 * vec3(clamp((mod(gl_FragCoord.x, 2.0) - 1.0) * 2.0, 0.0, 1.0)); vec4 tvhs = vec4(vhsCol * 1.05, 1.0); vec3 finalColor = clamp(tvhs.xyz, 0.0, 1.0); gl_FragColor = vec4(finalColor, 1.0); }
// ╔═════════════╦════════════════╗ // ║ Marco Gomez ║ https://mgz.me ║ // ╚═════════════╩════════════════╝ precision highp float; uniform sampler2D noiseTexture; uniform sampler2D prgm2Texture; uniform vec2 resolution; uniform float time; vec4 rgbShift(vec2 p , vec4 shift) { shift *= 2.0 * shift.w - 1.0; vec2 rs = vec2(shift.x, -shift.y); vec2 gs = vec2(shift.y, -shift.z); vec2 bs = vec2(shift.z, -shift.x); float r = texture2D(prgm2Texture, p + rs, 0.0).x; float g = texture2D(prgm2Texture, p + gs, 0.0).y; float b = texture2D(prgm2Texture, p + bs, 0.0).z; return vec4(r,g,b,1.0); } vec4 noise(vec2 uv) { return texture2D(noiseTexture, uv, 0.0); } vec4 vec4pow(vec4 v, float p) { return vec4( pow(v.x, p), pow(v.y, p), pow(v.z, p), v.w ); } void main(void) { vec2 uv = gl_FragCoord.xy / resolution.xy; vec2 mo = uv * 2.0 - 1.0; mo *= 0.01; vec3 chromaticAberration; chromaticAberration.r = texture2D(prgm2Texture, uv - mo * 0.05, 0.0).r; chromaticAberration.g = texture2D(prgm2Texture, uv - mo * 0.15, 0.0).g; chromaticAberration.b = texture2D(prgm2Texture, uv - mo * 0.25, 0.0).b; vec4 color = vec4(vec3(0.0), 1.0); color.xyz = mix(color.xyz, chromaticAberration, 0.3); const float speed = 0.01; const float amplitude = 0.01; vec4 shift = vec4pow( noise( vec2(speed * time, speed * time / 25.0 ) ), 8.0 ) * vec4(vec3(amplitude), 1.0); color += rgbShift(uv, shift); gl_FragColor = color; }
xxxxxxxxxx
// ╔═════════════╦════════════════╗
// ║ Marco Gomez ║ https://mgz.me ║
// ╚═════════════╩════════════════╝
precision highp float;
uniform sampler2D prgm3Texture;
uniform vec2 resolution;
void main(void) {
vec2 uv = gl_FragCoord.xy / resolution.xy;
vec4 prgm3 = texture2D(prgm3Texture, uv);
gl_FragColor = vec4(prgm3.xyz, 1.0);
}
99 fps 15ms
00:00:00.31
0.00