diff --git a/www/css/ppty.css b/www/css/ppty.css deleted file mode 100644 index 73192fb..0000000 --- a/www/css/ppty.css +++ /dev/null @@ -1,50 +0,0 @@ -/* =========================================================== * - * Pseudo-Pseudo-Terminal Effect * -/* =========================================================== */ - -.ppty { - background-color: var(--theme-bg); - border: 0.5ch solid var(--theme-tty-border); - - margin: auto auto; - padding: 20px; - - position: relative; - height: auto; - - /* display: block; */ - /* flex-direction: column; */ - /* justify-content: start; */ - /* align-content: center; */ - /* align-items: start; */ - - overflow: hidden; -} - -.ppty-block { - color: var(--theme-tty-output); - - visibility: hidden; - white-space: nowrap; /* only break on
*/ -} - -.ppty-prompt { - color: var(--theme-tty-prompt); - - display: inline-block; - vertical-align: top; -} - -.ppty-command { - color: var(--theme-tty-command); - - width: 0px; - border-right: 1ch solid var(--theme-tty-output); - - display: inline-block; - vertical-align: top; - overflow: hidden; -} - -.ppty-output { -} diff --git a/www/css/shader-style.css b/www/css/shader-style.css new file mode 100644 index 0000000..9b39002 --- /dev/null +++ b/www/css/shader-style.css @@ -0,0 +1,11 @@ +.gl-canvas-bg { + display:block; + width: 100vw; + height: 100vh; + + position: fixed; + left: 0; + top: 0; + + z-index: -1; +} diff --git a/www/css/style.css b/www/css/style.css index f4d9a73..9a14616 100644 --- a/www/css/style.css +++ b/www/css/style.css @@ -1,27 +1,3 @@ body { background-color: var(--theme-bg); } - -#bg-canvas { - display:block; - position: fixed; - - inset: 0; - width: 100vw; - height: 100vh; - z-index: -1; -} - -.centered { - position: absolute; - inset: 0 0 0 0; - margin: auto; - - display: flex; -} - -.heading { - font-family: monospace; - font-size: 2em; - font-weight: bold; -} diff --git a/www/css/themes/core.css b/www/css/themes/core.css index 2c30107..b01cbaa 100644 --- a/www/css/themes/core.css +++ b/www/css/themes/core.css @@ -1,15 +1,11 @@ -.theme-base { +.theme-tty-base { color: var(--theme-base); } -.theme-bg { +.theme-tty-bg { color: var(--theme-bg); } -.theme-text { - color: var(--theme-text); -} - .theme-tty-prompt { color: var(--theme-tty-prompt); } @@ -18,10 +14,6 @@ color: var(--theme-tty-command); } -.theme-tty-output { - color: var(--theme-tty-output); -} - .theme-tty-warning { color: var(--theme-tty-warning); } diff --git a/www/css/themes/maps/rose-pine.css b/www/css/themes/maps/rose-pine.css index a4497d9..58a809b 100644 --- a/www/css/themes/maps/rose-pine.css +++ b/www/css/themes/maps/rose-pine.css @@ -20,12 +20,9 @@ Variables: :root { --theme-base: var(--palette-rose-pine-base); --theme-bg: var(--palette-rose-pine-base); - --theme-text: var(--palette-rose-pine-text); - - --theme-tty-border: var(--palette-rose-pine-rose); + --theme-tty-prompt: var(--palette-rose-pine-foam); --theme-tty-command: var(--palette-rose-pine-iris); - --theme-tty-output: var(--palette-rose-pine-text); --theme-tty-warning: var(--palette-rose-pine-gold); --theme-tty-error: var(--palette-rose-pine-love); /* --theme-tty-: var(--palette-rose-pine-); */ diff --git a/www/css/typing.css b/www/css/typing.css new file mode 100644 index 0000000..0dd1d88 --- /dev/null +++ b/www/css/typing.css @@ -0,0 +1,118 @@ +.centered { + position: absolute; + inset: 0 0 0 0; + margin: auto; + + display: flex; +} + +.heading { + font-family: monospace; + font-size: 2em; + font-weight: bold; + color: #ffc0cb; /* #ac4aed */ +} + +/* =========================================================== * + * Type Writer Effect * +/* =========================================================== */ + +#typing-wrapper { + margin: auto auto; + /* width: 71ch; /* prompt + command + cursor length */ + /* height: 21ch; */ + text-align: start; + + border: 0.5ch solid #ffc0cb; /* #ac4aed */ + background-color: var(--theme-bg); + padding: 20px; + + overflow: hidden; + display: flex; + flex-direction: column; + justify-content: start; + align-content: center; + align-items: start; + animation: kfs-ending 2s 10s forwards; +} + +#typing-prompt { + color: var(--theme-tty-prompt); + width: 10ch; /* prompt + command length */ + animation: kfs-typing 0.5s steps(4), kfs-cursor-blink 1.2s steps(1, start) 0.6s forwards; + white-space: nowrap; + overflow: hidden; + border-right: 1ch solid; + margin-bottom: 0.5ch; +} + +#typing-result { + color: var(--theme-tty-warning); + /* "4.8s" means the result is shown 1.8s after typing ends */ + animation: unhide 1s 1.8s forwards; + visibility: hidden; + white-space: nowrap; /* preserve linebreaks */ +} + +#typing-prompt-segfault { + color: var(--theme-tty-prompt); + width: 47ch; /* prompt + command length */ + /* animation: kfs-typing-segfault 3s steps(36) 2.6s, cursor-blink 0.6s steps(1, start) 3s infinite alternate; */ + animation: kfs-typing-segfault 3s steps(36) 4s forwards, cursor-blink-segfault 0.6s steps(1, start) 7.1s infinite alternate; + white-space: nowrap; + overflow: hidden; + border-right: 1ch solid; + margin-bottom: 0.5ch; + visibility: hidden; +} + +#typing-result-segfault { + /* "4.8s" means the result is shown 1.8s after typing ends */ + animation: unhide 1s 8.3s forwards; + visibility: hidden; + white-space: nowrap; /* preserve linebreaks */ +} + +@keyframes kfs-typing { + from { + width: 6ch; /* ignore prompt width */ + } +} + +@keyframes kfs-typing-segfault { + from { + width: 11ch; /* ignore prompt width */ + visibility: visible; + } + 25% { + width: 11ch; + } + to { + visibility: visible; + } +} + +@keyframes kfs-cursor-blink { + from { + border-color: transparent; + } + 50% { + border-color: currentColor; + } + to { + border-color: transparent; + } +} + +@keyframes cursor-blink-segfault { + 50% { + border-color: transparent; + } +} + +@keyframes unhide { + to { + visibility: visible; + } +} + diff --git a/www/index.html b/www/index.html index 166f674..48d1ebf 100644 --- a/www/index.html +++ b/www/index.html @@ -12,54 +12,42 @@ - + + - - - - -
-
+ -
-
- grub> -
- -
- boot -
- -
- ERROR: Root device mounted successfully, but /sbin/init does not exist.

- - - Bailing out, you are on your own.
- Good luck

-
- - sh: can't access tty; job control turned off

-
-
+
+
-
-
- [rootfs ]# -
- -
- do butterflies cry when they're sad? -
- -
- - Segmentation fault (core dumped) - -
+
+ grub> boot
- + +
+ ERROR: Root device mounted successfully, but /sbin/init does not exist.

+ + + Bailing out, you are on your own.
+ Good luck +


+ + sh: can't access tty; job control turned off

+
+ + +
+ [rootfs ]# do butterflies cry when they're sad? +
+ +
+ + Segmentation fault (core dumped) + +
+
diff --git a/www/js/main.js b/www/js/main.js index da2444c..a5ca67b 100644 --- a/www/js/main.js +++ b/www/js/main.js @@ -1,59 +1,24 @@ -import { Smc, fetchShader } from "./smc/lib.js"; -import { PPTY } from "./ppty/lib.js"; +import { Smc } from "./smc/smc.js" main(); -function endBoot(root) { - const style = getComputedStyle(root); - const paddingLeft = parseFloat(style.paddingLeft); - const paddingRight = parseFloat(style.paddingRight); - const contentWidth = root.clientWidth - paddingLeft - paddingRight; - const paddingTop = parseFloat(style.paddingTop); - const paddingBottom = parseFloat(style.paddingBottom); - const contentHeight = root.clientHeight - paddingTop - paddingBottom; - - root.style.width = `${contentWidth}px`; - root.style.height = `${contentHeight}px`; - - const fade = root.animate( - [{ opacity: 0 }], - { - duration: 400, - delay: 3000, - fill: "forwards", - } - ); - - fade.onfinish = () => root.remove(); +async function fetchShader(uri, delegate) { + const res = await fetch(uri); + if (res.ok) + return await res.text(); + this.raiseError( + SmcErr.FETCH_SHADER, + `Failed to load shader source ${url}: ${res.status} ${res.json()}`); + return "" } -function main() { - const boot = document.querySelector("#boot-ppty") - new PPTY( - boot, - [ - { - cps: 12, - promptDelay: 0.5, - commandDelay: 0.7, - outputDelay: 1, - blinkTime: 0.6, - }, - { - cps: 10, - promptDelay: 0, - commandDelay: 1.5, - outputDelay: 1.2, - blinkTime: 0.6, - } - ]) - .onfinish(endBoot) - .run(); - const canvas = document.querySelector("#bg-canvas"); +function main() { + const canvas = document.querySelector("#gl-canvas"); canvas.setAttribute('width', window.innerWidth); canvas.setAttribute('height', window.innerHeight); + fetchShader("../shaders/segfault.glsl") .then(frag => new Smc(canvas) diff --git a/www/js/ppty/lib.js b/www/js/ppty/lib.js deleted file mode 100644 index 2646e23..0000000 --- a/www/js/ppty/lib.js +++ /dev/null @@ -1,2 +0,0 @@ -import { PPTY } from "./ppty.js"; -export { PPTY }; diff --git a/www/js/ppty/ppty.js b/www/js/ppty/ppty.js deleted file mode 100644 index a471e3f..0000000 --- a/www/js/ppty/ppty.js +++ /dev/null @@ -1,130 +0,0 @@ -export { PPTY }; - -function animDelta(anim) { - const timing = anim.effect.getComputedTiming(); - return (timing.delay ?? 0) + (timing.duration ?? 0) + (timing.endDelay ?? 0); -} - -class PPTY { - #root; - #blockOptions; - #startCallback = _ => { }; - #finishCallback = _ => { }; - - constructor(root, blockOptions) { - this.#root = root; - this.#blockOptions = blockOptions; - } - - onstart(handler) { - this.#startCallback = handler; - return this; - } - - onfinish(handler) { - this.#finishCallback = handler; - return this; - } - - run() { - var delay = 0; - - this.#startCallback(this.#root); - - this.#root - .querySelectorAll(".ppty-block") - .forEach((block, index, blocks) => { - const prompt = block.querySelector(".ppty-prompt"); - const command = block.querySelector(".ppty-command"); - const output = block.querySelector(".ppty-output"); - - const options = this.#blockOptions[index]; - const cps = options["cps"]; // chars per second - const promptDelay = options["promptDelay"] * 1000; - const commandDelay = options["commandDelay"] * 1000; - const outputDelay = options["outputDelay"] * 1000; - const blinkTime = options["blinkTime"] * 2 * 1000; // x2 then x1000 - - // WARNING: ensure prompt|command|output != null - const promptAnim = prompt.animate( - [{ visibility: "visible" }], - { - delay: delay + promptDelay, - fill: "forwards", - }, - ); - delay = animDelta(promptAnim); - - const showCursor = () => { command.style.borderRightColor = cursorColor; return true; }; - const hideCursor = () => { command.style.borderRightColor = "transparent"; return false; }; - const startCursorBlink = () => setInterval(() => { - cursorVisible = cursorVisible ? hideCursor() : showCursor(); - }, blinkTime); - - const cursorColor = command.style.borderRightColor; - var cursorVisible = true; - var blinkId = null; - setTimeout(() => { - command.style.visibility = "visible"; - blinkId = startCursorBlink(); - }, delay); - - // WARNING: ensure command.textContent != null - const commandLen = command.textContent.trim().length - const commandAnim = command.animate( - [ - { - width: "0ch", - visibility: "visible", - }, - { - width: `${commandLen}ch`, - visibility: "visible", - } - ], - { - duration: commandLen / cps * 1000, - delay: delay + commandDelay, - easing: `steps(${commandLen}, end)`, - fill: "forwards", - } - ); - // pause the cursor while typing - setTimeout(() => { - clearInterval(blinkId); - showCursor(); - cursorVisible = true; - }, delay + commandDelay); - delay = animDelta(commandAnim); - setTimeout(() => { - blinkId = startCursorBlink(); - }, delay); - - // delay until output is visible - delay += outputDelay; - setTimeout(() => { - clearInterval(blinkId); - hideCursor(); - }, delay); - - // unhide output - output.animate( - [{ visibility: "visible" }], - { - delay: delay, - fill: "forwards", - } - ); - - // hide the cursor after output displays and run the callback - setTimeout(() => { - command.style.borderRightColor = "transparent"; - if (index == blocks.length - 1) - this.#finishCallback(this.#root); - }, delay); - }); - } -} - - - diff --git a/www/js/smc/lib.js b/www/js/smc/lib.js index 0635b4c..cbff55e 100644 --- a/www/js/smc/lib.js +++ b/www/js/smc/lib.js @@ -1,14 +1,4 @@ import { Smc } from "./smc.js"; import { SmcErr } from "./errors.js"; -export { Smc, SmcErr, fetchShader }; - -async function fetchShader(uri, delegate) { - const res = await fetch(uri); - if (res.ok) - return await res.text(); - this.raiseError( - SmcErr.FETCH_SHADER, - `Failed to load shader source ${url}: ${res.status} ${res.json()}`); - return "" -} +export { Smc, SmcErr }; diff --git a/www/js/smc/smc.js b/www/js/smc/smc.js index f81b8cb..9829921 100644 --- a/www/js/smc/smc.js +++ b/www/js/smc/smc.js @@ -164,11 +164,10 @@ class Smc { var delta = time - this.#prevTimeMs; this.render(time, delta); - requestAnimationFrame(this.renderLoop); - // setTimeout( - // () => requestAnimationFrame(this.renderLoop), - // Math.max(0, delta - this.#minDeltaTimeMs) - // ); + setTimeout( + () => requestAnimationFrame(this.renderLoop), + Math.max(0, delta - this.#minDeltaTimeMs) + ); this.#prevTimeMs = time; } diff --git a/www/shaders/sample.glsl b/www/shaders/sample.glsl new file mode 100644 index 0000000..9b54b8f --- /dev/null +++ b/www/shaders/sample.glsl @@ -0,0 +1,23 @@ +precision mediump float; + +// uniform float uTime; +uniform vec2 uResolution; + +void main() { + vec2 uv = gl_FragCoord.xy / uResolution.xy; + // vec3 col = 0.5 + 0.5 * cos(uTime + uv.xyx + vec3(0, 2, 4)); + // gl_FragColor = vec4(col, 1.0); + // gl_FragColor = vec4(216., 43., 72., 255.) / 255.; + + + // float maxfc = max(gl_FragCoord.x, gl_FragCoord.y); + // gl_FragColor = vec4(gl_FragCoord.xy, maxfc, maxfc) / maxfc; + + float maxuv = max(uv.x, uv.y); + gl_FragColor = vec4(34., 43., 192.*maxuv, 255.) / 255.; + + + // vec3 col = 0.5 + 0.5*cos(uv.xyx+vec3(0,2,4)); + // gl_FragColor = vec4(col, 1.); +} + diff --git a/www/shaders/segfault.glsl b/www/shaders/segfault.glsl index 463fb45..a96bb19 100644 --- a/www/shaders/segfault.glsl +++ b/www/shaders/segfault.glsl @@ -15,8 +15,9 @@ uniform float uTime; uniform vec2 uResolution; /* ==== Text Colouring ==== */ -#define PHOSPHOR_COL vec4(224./255., 222./255., 244./255., 1.) -#define BG_COL vec4(24./255., 23./255., 30./255., 1.) +#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.) diff --git a/www/shaders/working.glsl b/www/shaders/working.glsl new file mode 100644 index 0000000..71a0872 --- /dev/null +++ b/www/shaders/working.glsl @@ -0,0 +1,368 @@ +// WARNING: NOTE: this works on https://glslsandbox.com/e +precision highp float; + +uniform float time; +uniform vec2 resolution; + +/* ==== Text Colouring ==== */ +#define PHOSPHOR_COL vec4(1, 1., 1., 1.) +#define BG_COL vec4(0.2, 0.0, 0.2, 0.) +/* ======= Text Size ======= */ +#define FONT_SIZE vec2(10.,20.) +#define ROWCOLS vec2(80., 24.) +/* === Text Bloom Effect === */ +#define WIDTH 1.2 +#define HEIGHT 0.7 +#define SMOOTH 0.004 +/* ====== Smoke Noise ====== */ +const int noiseSwirlSteps = 0; +const float noiseSwirlValue = 1.; +const float noiseSwirlStepValue = noiseSwirlValue / float(noiseSwirlSteps); +const float noiseScale = 1.0; +const float noiseTimeScale = 0.1; + +// =================================================================== +// Library Functions +// +float rand(vec2 co) { + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +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; +} + +// standard roundSquare +float stdRS(vec2 uv, float r) { + return roundSquare(uv - 0.5, vec2(WIDTH, HEIGHT) + r, 0.05); +} + +// =================================================================== +// Description : Array and textureless GLSL 2D/3D/4D simplex +// noise functions. +// Author : Ian McEwan, Ashima Arts. +// Maintainer : ijm +// Lastmod : 20110822 (ijm) +// License : Copyright (C) 2011 Ashima Arts. All rights reserved. +// Distributed under the MIT License. See LICENSE file. +// https://github.com/ashima/webgl-noise +// +vec3 mod289(vec3 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec4 mod289(vec4 x) { + return x - floor(x * (1.0 / 289.0)) * 289.0; +} + +vec4 permute(vec4 x) { + return mod289(((x*34.0)+1.0)*x); +} + +vec4 taylorInvSqrt(vec4 r) { + return 1.79284291400159 - 0.85373472095314 * r; +} + +float simplex(vec3 v) { + const vec2 C = vec2(1.0/6.0, 1.0/3.0) ; + const vec4 D = vec4(0.0, 0.5, 1.0, 2.0); + + // First corner + vec3 i = floor(v + dot(v, C.yyy) ); + vec3 x0 = v - i + dot(i, C.xxx) ; + + // Other corners + vec3 g = step(x0.yzx, x0.xyz); + vec3 l = 1.0 - g; + vec3 i1 = min( g.xyz, l.zxy ); + vec3 i2 = max( g.xyz, l.zxy ); + + vec3 x1 = x0 - i1 + C.xxx; + vec3 x2 = x0 - i2 + C.yyy; + vec3 x3 = x0 - D.yyy; + + // Permutations + i = mod289(i); + vec4 p = permute( permute( permute( + i.z + vec4(0.0, i1.z, i2.z, 1.0 )) + + i.y + vec4(0.0, i1.y, i2.y, 1.0 )) + + i.x + vec4(0.0, i1.x, i2.x, 1.0 )); + + // Gradients: 7x7 points over a square, mapped onto an octahedron. + // The ring size 17*17 = 289 is close to a multiple of 49 (49*6 = 294) + float n_ = 0.142857142857; // 1.0/7.0 + vec3 ns = n_ * D.wyz - D.xzx; + + vec4 j = p - 49.0 * floor(p * ns.z * ns.z); // mod(p,7*7) + + vec4 x_ = floor(j * ns.z); + vec4 y_ = floor(j - 7.0 * x_ ); // mod(j,N) + + vec4 x = x_ *ns.x + ns.yyyy; + vec4 y = y_ *ns.x + ns.yyyy; + vec4 h = 1.0 - abs(x) - abs(y); + + vec4 b0 = vec4( x.xy, y.xy ); + vec4 b1 = vec4( x.zw, y.zw ); + + vec4 s0 = floor(b0)*2.0 + 1.0; + vec4 s1 = floor(b1)*2.0 + 1.0; + vec4 sh = -step(h, vec4(0.0)); + + vec4 a0 = b0.xzyw + s0.xzyw*sh.xxyy ; + vec4 a1 = b1.xzyw + s1.xzyw*sh.zzww ; + + vec3 p0 = vec3(a0.xy,h.x); + vec3 p1 = vec3(a0.zw,h.y); + vec3 p2 = vec3(a1.xy,h.z); + vec3 p3 = vec3(a1.zw,h.w); + + //Normalise gradients + vec4 norm = taylorInvSqrt(vec4(dot(p0,p0), dot(p1,p1), dot(p2, p2), dot(p3,p3))); + p0 *= norm.x; + p1 *= norm.y; + p2 *= norm.z; + p3 *= norm.w; + + // Mix final noise value + vec4 m = max(0.6 - vec4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0); + m = m * m; + return 42.0 * dot( m*m, vec4( dot(p0,x0), dot(p1,x1), dot(p2,x2), dot(p3,x3) ) ); +} + + +// =================================================================== +// 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 (resolution.y < 320.) // attempt to get rid of aliasing on small resolution + return smoothstep(1.0, 0.9, f); + else if (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; +} + + +// =================================================================== +// Noise Generation Algorithms +// textLines(...) is for simulating the writing of random characters in line formats +// https://www.shadertoy.com/view/llSXDV (same author as VT220 font rendering) +// +// smokeNoise(...) is for the main noise generation algorithm (very tunable) +// https://www.shadertoy.com/view/MsdGWn +// +float textLines(vec2 uvG) { + float wt = 5. * (time + 0.5*sin(time*1.4) + 0.2*sin(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.; +} + +float fbm3(vec3 v) { + float result = simplex(v); + result += simplex(v * 2.) / 2.; + result += simplex(v * 4.) / 4.; + result /= (1. + 1./2. + 1./4.); + return result; +} + +float fbm5(vec3 v) { + float result = simplex(v); + result += simplex(v * 2.) / 2.; + result += simplex(v * 4.) / 4.; + result += simplex(v * 8.) / 8.; + result += simplex(v * 16.) / 16.; + result /= (1. + 1./2. + 1./4. + 1./8. + 1./16.); + return result; +} + +float smokeNoise(vec3 v) { + // make it curl + for (int i=0; i