324 lines
9.8 KiB
Text
324 lines
9.8 KiB
Text
|
|
/* BTW: You can use ANY function as the noise/plasma function
|
||
|
|
* It just needs to return a float in the range 0.0 - 17.0
|
||
|
|
* But shouldn't return 0.0 or 17.0 (they're exclusive bounds).
|
||
|
|
* View this shader on shadertoy: https://www.shadertoy.com/view/t3tSRj#
|
||
|
|
*/
|
||
|
|
|
||
|
|
// is highp wasteful for this shader?
|
||
|
|
#ifdef GL_ES
|
||
|
|
# ifdef GL_FRAGMENT_PRECISION_HIGH
|
||
|
|
precision highp float;
|
||
|
|
# else
|
||
|
|
precision mediump float;
|
||
|
|
# endif
|
||
|
|
#endif
|
||
|
|
|
||
|
|
uniform float u_time;
|
||
|
|
uniform vec2 u_resolution;
|
||
|
|
|
||
|
|
/* ==== Text Colouring ==== */
|
||
|
|
#define PHOSPHOR_COL vec4(196./255., 167./255., 231./255., 1.)
|
||
|
|
// #define BG_COL vec4(0.2, 0.0, 0.2, 0.5)
|
||
|
|
#define BG_COL vec4(14./255., 13./255., 20./255., 1.)
|
||
|
|
/* ======= Text Size ======= */
|
||
|
|
#define FONT_SIZE vec2(10.,20.)
|
||
|
|
#define ROWCOLS vec2(80., 24.)
|
||
|
|
|
||
|
|
// ===================================================================
|
||
|
|
// Library Functions
|
||
|
|
//
|
||
|
|
float rand (in vec2 _st) {
|
||
|
|
return fract(sin(dot(_st.xy, vec2(12.9898,78.233))) * 43758.5453123);
|
||
|
|
}
|
||
|
|
|
||
|
|
float quantise(float val, float n) {
|
||
|
|
return clamp(floor(val * n), 0.0, n) / n;
|
||
|
|
}
|
||
|
|
|
||
|
|
float roundSquare(vec2 p, vec2 b, float r) {
|
||
|
|
return length(max(abs(p)-b,0.0))-r;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// ===================================================================
|
||
|
|
// VT220 Font Rendering
|
||
|
|
// Author/Source : https://www.shadertoy.com/view/llSXDV
|
||
|
|
//
|
||
|
|
#define l(y,a,b) roundLine(p, vec2(float(a), float(y)), vec2(float(b), float(y)))
|
||
|
|
float roundLine(vec2 p, vec2 a, vec2 b) {
|
||
|
|
b -= a + vec2(1.0,0.);
|
||
|
|
p -= a;
|
||
|
|
float f = length(p-clamp(dot(p,b)/dot(b,b),0.0,1.0)*b);
|
||
|
|
if (u_resolution.y < 320.) // attempt to get rid of aliasing on small resolution
|
||
|
|
return smoothstep(1.0, 0.9, f);
|
||
|
|
else if (u_resolution.y < 720.)
|
||
|
|
return smoothstep(0.75, 0.5, f);
|
||
|
|
else
|
||
|
|
return smoothstep(1., 0., f);
|
||
|
|
}
|
||
|
|
|
||
|
|
float vt220Font(vec2 p, float c) {
|
||
|
|
if (c < 1.) return 0.;
|
||
|
|
if (p.y > 16.) {
|
||
|
|
if (c > 2.) return 0.0;
|
||
|
|
if (c > 1.) return l(17,1,9);
|
||
|
|
}
|
||
|
|
if (p.y > 14.) {
|
||
|
|
if (c > 16.) return l(15,3,8);
|
||
|
|
if (c > 15.) return l(15,1,8);
|
||
|
|
if (c > 14.) return l(15,1,3)+ l(15,7,9);
|
||
|
|
if (c > 13.) return l(15,2,8);
|
||
|
|
if (c > 12.) return l(15,1,9);
|
||
|
|
if (c > 11.) return l(15,2,8);
|
||
|
|
if (c > 10.) return l(15,1,3)+ l(15,6,8);
|
||
|
|
if (c > 9.) return l(15,4,6);
|
||
|
|
if (c > 8.) return l(15,2,4)+ l(15,5,7);
|
||
|
|
if (c > 7.) return l(15,2,8);
|
||
|
|
if (c > 6.) return l(15,2,8);
|
||
|
|
if (c > 5.) return l(15,2,8);
|
||
|
|
if (c > 4.) return l(15,2,9);
|
||
|
|
if (c > 3.) return l(15,1,8);
|
||
|
|
if (c > 2.) return l(15,2,9);
|
||
|
|
}
|
||
|
|
if (p.y > 12.) {
|
||
|
|
if (c > 16.) return l(13,2,4)+ l(13,7,9);
|
||
|
|
if (c > 15.) return l(13,2,4)+ l(13,7,9);
|
||
|
|
if (c > 14.) return l(13,1,3)+ l(13,7,9);
|
||
|
|
if (c > 13.) return l(13,1,3)+ l(13,7,9);
|
||
|
|
if (c > 12.) return l(13,1,3);
|
||
|
|
if (c > 11.) return l(13,4,6);
|
||
|
|
if (c > 10.) return l(13,2,4)+ l(13,5,9);
|
||
|
|
if (c > 9.) return l(13,2,8);
|
||
|
|
if (c > 8.) return l(13,2,4)+ l(13,5,7);
|
||
|
|
if (c > 7.) return l(13,1,3)+ l(13,7,9);
|
||
|
|
if (c > 6.) return l(13,1,3)+ l(13,7,9);
|
||
|
|
if (c > 5.) return l(13,1,3)+ l(13,7,9);
|
||
|
|
if (c > 4.) return l(13,1,3)+ l(15,2,9);
|
||
|
|
if (c > 3.) return l(13,1,4)+ l(13,7,9);
|
||
|
|
if (c > 2.) return l(13,1,3)+ l(13,6,9);
|
||
|
|
}
|
||
|
|
if (p.y > 10.) {
|
||
|
|
if (c > 16.) return l(11,1,3);
|
||
|
|
if (c > 15.) return l(11,2,4)+ l(11,7,9);
|
||
|
|
if (c > 14.) return l(11,1,9);
|
||
|
|
if (c > 13.) return l(11,7,9);
|
||
|
|
if (c > 12.) return l(11,2,5);
|
||
|
|
if (c > 11.) return l(11,4,6);
|
||
|
|
if (c > 10.) return l(11,3,5)+ l(11,6,8);
|
||
|
|
if (c > 9.) return l(11,4,6)+ l(11,7,9);
|
||
|
|
if (c > 8.) return l(11,1,8);
|
||
|
|
if (c > 7.) return l(11,1,3)+ l(11,7,9);
|
||
|
|
if (c > 6.) return l(11,1,3)+ l(11,7,9);
|
||
|
|
if (c > 5.) return l(11,1,3)+ l(11,7,9);
|
||
|
|
if (c > 4.) return l(11,1,3);
|
||
|
|
if (c > 3.) return l(11,1,3)+ l(11,7,9);
|
||
|
|
if (c > 2.) return l(11,2,9);
|
||
|
|
}
|
||
|
|
if (p.y > 8.) {
|
||
|
|
if (c > 16.) return l(9,1,3);
|
||
|
|
if (c > 15.) return l(9,2,8);
|
||
|
|
if (c > 14.) return l(9,1,3)+ l(9,7,9);
|
||
|
|
if (c > 13.) return l(9,4,8);
|
||
|
|
if (c > 12.) return l(9,4,8);
|
||
|
|
if (c > 11.) return l(9,4,6);
|
||
|
|
if (c > 10.) return l(9,4,6);
|
||
|
|
if (c > 9.) return l(9,2,8);
|
||
|
|
if (c > 8.) return l(9,2,4)+ l(9,5,7);
|
||
|
|
if (c > 7.) return l(9,1,3)+ l(9,7,9);
|
||
|
|
if (c > 6.) return l(9,1,3)+ l(9,7,9);
|
||
|
|
if (c > 5.) return l(9,1,3)+ l(9,7,9);
|
||
|
|
if (c > 4.) return l(9,1,3)+ l(9,7,9);
|
||
|
|
if (c > 3.) return l(9,1,4)+ l(9,7,9);
|
||
|
|
if (c > 2.) return l(9,7,9);
|
||
|
|
}
|
||
|
|
if (p.y > 6.) {
|
||
|
|
if (c > 16.) return l(7,1,3);
|
||
|
|
if (c > 15.) return l(7,2,4)+ l(7,7,9);
|
||
|
|
if (c > 14.) return l(7,2,4)+ l(7,6,8);
|
||
|
|
if (c > 13.) return l(7,5,7);
|
||
|
|
if (c > 12.) return l(7,7,9);
|
||
|
|
if (c > 11.) return l(7,2,6);
|
||
|
|
if (c > 10.) return l(7,2,4)+ l(7,5,7);
|
||
|
|
if (c > 9.) return l(7,1,3)+ l(7,4,6);
|
||
|
|
if (c > 8.) return l(7,1,8);
|
||
|
|
if (c > 7.) return l(7,2,8);
|
||
|
|
if (c > 6.) return l(7,2,8);
|
||
|
|
if (c > 5.) return l(7,2,8);
|
||
|
|
if (c > 4.) return l(7,2,8);
|
||
|
|
if (c > 3.) return l(7,1,8);
|
||
|
|
if (c > 2.) return l(7,2,8);
|
||
|
|
}
|
||
|
|
if (p.y > 4.) {
|
||
|
|
if (c > 16.) return l(5,2,4)+ l(5,7,9);
|
||
|
|
if (c > 15.) return l(5,2,4)+ l(5,7,9);
|
||
|
|
if (c > 14.) return l(5,3,7);
|
||
|
|
if (c > 13.) return l(5,6,8);
|
||
|
|
if (c > 12.) return l(5,1,3)+ l(5,7,9);
|
||
|
|
if (c > 11.) return l(5,3,6);
|
||
|
|
if (c > 10.) return l(5,1,5)+ l(5,6,8);
|
||
|
|
if (c > 9.) return l(5,2,8);
|
||
|
|
if (c > 8.) return l(5,2,4)+ l(5,5,7);
|
||
|
|
if (c > 7.) return 0.;
|
||
|
|
if (c > 6.) return 0.;
|
||
|
|
if (c > 5.) return 0.;
|
||
|
|
if (c > 4.) return 0.;
|
||
|
|
if (c > 3.) return l(5,1,3);
|
||
|
|
if (c > 2.) return 0.;
|
||
|
|
}
|
||
|
|
if (p.y > 2.) {
|
||
|
|
if (c > 16.) return l(3,3,8);
|
||
|
|
if (c > 15.) return l(3,1,8);
|
||
|
|
if (c > 14.) return l(3,4,6);
|
||
|
|
if (c > 13.) return l(3,1,9);
|
||
|
|
if (c > 12.) return l(3,2,8);
|
||
|
|
if (c > 11.) return l(3,4,6);
|
||
|
|
if (c > 10.) return l(3,2,4)+ l(3,7,9);
|
||
|
|
if (c > 9.) return l(3,4,6);
|
||
|
|
if (c > 8.) return l(3,2,4)+ l(3,5,7);
|
||
|
|
if (c > 7.) return l(3,2,4)+ l(3,6,8);
|
||
|
|
if (c > 6.) return l(3,1,3)+ l(3,4,7);
|
||
|
|
if (c > 5.) return l(3,2,4)+ l(3,6,8);
|
||
|
|
if (c > 4.) return 0.;
|
||
|
|
if (c > 3.) return l(3,1,3);
|
||
|
|
if (c > 2.) return 0.;
|
||
|
|
}
|
||
|
|
else {
|
||
|
|
if (c > 7.) return 0.;
|
||
|
|
if (c > 6.) return l(1,2,5)+ l(1,6,8);
|
||
|
|
}
|
||
|
|
return 0.0;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// ===================================================================
|
||
|
|
// Text Effects
|
||
|
|
// textLines(...) is for simulating the writing of random characters in line formats
|
||
|
|
// https://www.shadertoy.com/view/llSXDV (same author as VT220 font rendering)
|
||
|
|
//
|
||
|
|
float textLines(vec2 uvG) {
|
||
|
|
float wt = 5. * (u_time + 0.5*sin(u_time*1.4) + 0.2*sin(u_time*2.9)); // wobbly time
|
||
|
|
vec2 uvGt = uvG + vec2(0., floor(wt));
|
||
|
|
float ll = rand(vec2(uvGt.y, - 1.)) * ROWCOLS.x; // line length
|
||
|
|
|
||
|
|
if (uvG.y > ROWCOLS.y - 2.){
|
||
|
|
if (ceil(uvG.x) == floor(min(ll, fract(wt)*ROWCOLS.x)))
|
||
|
|
return 2.;
|
||
|
|
if (ceil(uvG.x) > floor(min(ll, fract(wt)*ROWCOLS.x)))
|
||
|
|
return 0.;
|
||
|
|
}
|
||
|
|
if (uvGt.x > 5. && rand(uvGt) < .075)
|
||
|
|
return 0.;
|
||
|
|
if (max(5., uvGt.x) > ll)
|
||
|
|
return 0.;
|
||
|
|
|
||
|
|
return rand(uvGt)*15. + 2.;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
// ===================================================================
|
||
|
|
// Noise Generation Algorithms
|
||
|
|
// noise(...) is for the main noise generation algorithm (very tunable)
|
||
|
|
// https://www.shadertoy.com/view/MsdGWn
|
||
|
|
//
|
||
|
|
|
||
|
|
// Based on Morgan McGuire @morgan3d
|
||
|
|
// https://www.shadertoy.com/view/4dS3Wd
|
||
|
|
float noise (in vec2 _st) {
|
||
|
|
vec2 i = floor(_st);
|
||
|
|
vec2 f = fract(_st);
|
||
|
|
|
||
|
|
// Four corners in 2D of a tile
|
||
|
|
float a = rand(i);
|
||
|
|
float b = rand(i + vec2(1.0, 0.0));
|
||
|
|
float c = rand(i + vec2(0.0, 1.0));
|
||
|
|
float d = rand(i + vec2(1.0, 1.0));
|
||
|
|
|
||
|
|
vec2 u = f * f * (3.0 - 2.0 * f);
|
||
|
|
|
||
|
|
return mix(a, b, u.x) +
|
||
|
|
(c - a)* u.y * (1.0 - u.x) +
|
||
|
|
(d - b) * u.x * u.y;
|
||
|
|
}
|
||
|
|
|
||
|
|
#define NUM_OCTAVES 100
|
||
|
|
// Brightness (0.0 - 1.0)
|
||
|
|
#define BRIGHTNESS 0.55
|
||
|
|
#define LACUNARITY 2.0
|
||
|
|
#define GAIN 0.5
|
||
|
|
#define SHIFT 100.0
|
||
|
|
|
||
|
|
// VAR_THETA defines whether to compute
|
||
|
|
// sin/cos values at runtime or
|
||
|
|
#define VAR_THETA 0
|
||
|
|
#define THETA 0.5
|
||
|
|
#if (VAR_THETA == 1)
|
||
|
|
#endif
|
||
|
|
|
||
|
|
float fbm( in vec2 _st) {
|
||
|
|
float v = 0.0;
|
||
|
|
float a = BRIGHTNESS;
|
||
|
|
// Rotate to reduce axial bias
|
||
|
|
mat2 T = LACUNARITY * mat2(cos(THETA), sin(THETA),
|
||
|
|
-sin(THETA), cos(THETA));
|
||
|
|
for (int i = 0; i < NUM_OCTAVES; ++i) {
|
||
|
|
_st = T * _st + SHIFT;
|
||
|
|
v += noise(_st) * a;
|
||
|
|
a *= GAIN;
|
||
|
|
}
|
||
|
|
return v;
|
||
|
|
}
|
||
|
|
|
||
|
|
|
||
|
|
#define SCALE_UV 3.
|
||
|
|
#define SCALE_TIME 1.
|
||
|
|
|
||
|
|
// XXX: TODO: use two shaders, the first on a MUCH lower resolution (one pixel for each text character)
|
||
|
|
// XXX: TODO: then the second should map those pixel values to higher resolution text characters
|
||
|
|
void main() {
|
||
|
|
vec2 uv = gl_FragCoord.xy / u_resolution;
|
||
|
|
vec2 st = uv * SCALE;
|
||
|
|
|
||
|
|
// // uvNoise = ceil(uvNoise * ROWCOLS) / ROWCOLS;
|
||
|
|
// float val = noise(st);
|
||
|
|
// // Noise is fed through a sigmoid function, then quantised to integer range 0-17
|
||
|
|
// val = (exp(val) / 2.71828); // increase contrast (normalised 0.0 - 1.0)
|
||
|
|
// val = 1.0 / val;
|
||
|
|
// val *= 1.0 / (1.0 + exp(-val)) - 0.5; // subtraction value is tunable (range 0.0 - 0.5)
|
||
|
|
// val *= quantise(val, 17.0); // quantise by 17 then normalise back to 0.0 - 1.0
|
||
|
|
// val = pow(18.0, val) - 1.0; // TODO: try changing 18.0 to 200.0 and you'll notice some pretty changes :)
|
||
|
|
|
||
|
|
// // VT220 Font Rendering
|
||
|
|
// vec2 base = uv;
|
||
|
|
// base.y = 1 - base.y;
|
||
|
|
// vec2 uvT = ROWCOLS * FONT_SIZE * base;
|
||
|
|
// vec2 uvG = floor(ROWCOLS * base;
|
||
|
|
// gl_FragColor = vt220Font(uvT - uvG * FONT_SIZE, val) * PHOSPHOR_COL + BG_COL;
|
||
|
|
|
||
|
|
vec2 q = vec2(
|
||
|
|
fbm( st + 0.*u_time),
|
||
|
|
fbm( st + vec2(1.0))
|
||
|
|
);
|
||
|
|
|
||
|
|
vec2 r = vec2(
|
||
|
|
fbm( st + 1.0*q + vec2(1.7,9.2)+ 0.15*u_time ),
|
||
|
|
fbm( st + 1.0*q + vec2(8.3,2.8)+ 0.126*u_time)
|
||
|
|
);
|
||
|
|
|
||
|
|
float f = fbm(st+r);
|
||
|
|
|
||
|
|
vec3 color = mix(vec3(0.101961,0.619608,0.666667),
|
||
|
|
vec3(0.666667,0.666667,0.498039),
|
||
|
|
clamp((f*f)*4.0,0.0,1.0));
|
||
|
|
|
||
|
|
color = mix(color,
|
||
|
|
vec3(0,0,0.164706),
|
||
|
|
clamp(length(q),0.0,1.0));
|
||
|
|
|
||
|
|
color = mix(color,
|
||
|
|
vec3(0.666667,1,1),
|
||
|
|
clamp(length(r.x),0.0,1.0));
|
||
|
|
|
||
|
|
gl_FragColor = vec4((f*f*f+.6*f*f+.5*f)*color,1.);
|
||
|
|
}
|
||
|
|
|