diff --git a/www/css/ppty.css b/www/css/ppty.css new file mode 100644 index 0000000..73192fb --- /dev/null +++ b/www/css/ppty.css @@ -0,0 +1,50 @@ +/* =========================================================== * + * 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 deleted file mode 100644 index 9b39002..0000000 --- a/www/css/shader-style.css +++ /dev/null @@ -1,11 +0,0 @@ -.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 9a14616..f4d9a73 100644 --- a/www/css/style.css +++ b/www/css/style.css @@ -1,3 +1,27 @@ 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 b01cbaa..2c30107 100644 --- a/www/css/themes/core.css +++ b/www/css/themes/core.css @@ -1,11 +1,15 @@ -.theme-tty-base { +.theme-base { color: var(--theme-base); } -.theme-tty-bg { +.theme-bg { color: var(--theme-bg); } +.theme-text { + color: var(--theme-text); +} + .theme-tty-prompt { color: var(--theme-tty-prompt); } @@ -14,6 +18,10 @@ 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 58a809b..a4497d9 100644 --- a/www/css/themes/maps/rose-pine.css +++ b/www/css/themes/maps/rose-pine.css @@ -20,9 +20,12 @@ 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 deleted file mode 100644 index 0dd1d88..0000000 --- a/www/css/typing.css +++ /dev/null @@ -1,118 +0,0 @@ -.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 48d1ebf..166f674 100644 --- a/www/index.html +++ b/www/index.html @@ -12,42 +12,54 @@ - - + - - + + + +
-
- -
- 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 a5ca67b..da2444c 100644 --- a/www/js/main.js +++ b/www/js/main.js @@ -1,24 +1,59 @@ -import { Smc } from "./smc/smc.js" +import { Smc, fetchShader } from "./smc/lib.js"; +import { PPTY } from "./ppty/lib.js"; main(); -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 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(); } - function main() { - const canvas = document.querySelector("#gl-canvas"); + 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"); 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 new file mode 100644 index 0000000..2646e23 --- /dev/null +++ b/www/js/ppty/lib.js @@ -0,0 +1,2 @@ +import { PPTY } from "./ppty.js"; +export { PPTY }; diff --git a/www/js/ppty/ppty.js b/www/js/ppty/ppty.js new file mode 100644 index 0000000..a471e3f --- /dev/null +++ b/www/js/ppty/ppty.js @@ -0,0 +1,130 @@ +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 cbff55e..0635b4c 100644 --- a/www/js/smc/lib.js +++ b/www/js/smc/lib.js @@ -1,4 +1,14 @@ import { Smc } from "./smc.js"; import { SmcErr } from "./errors.js"; -export { Smc, SmcErr }; +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 "" +} diff --git a/www/js/smc/smc.js b/www/js/smc/smc.js index 9829921..f81b8cb 100644 --- a/www/js/smc/smc.js +++ b/www/js/smc/smc.js @@ -164,10 +164,11 @@ class Smc { var delta = time - this.#prevTimeMs; this.render(time, delta); - setTimeout( - () => requestAnimationFrame(this.renderLoop), - Math.max(0, delta - this.#minDeltaTimeMs) - ); + requestAnimationFrame(this.renderLoop); + // 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 deleted file mode 100644 index 9b54b8f..0000000 --- a/www/shaders/sample.glsl +++ /dev/null @@ -1,23 +0,0 @@ -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 a96bb19..463fb45 100644 --- a/www/shaders/segfault.glsl +++ b/www/shaders/segfault.glsl @@ -15,9 +15,8 @@ uniform float uTime; uniform vec2 uResolution; /* ==== 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.) +#define PHOSPHOR_COL vec4(224./255., 222./255., 244./255., 1.) +#define BG_COL vec4(24./255., 23./255., 30./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 deleted file mode 100644 index 71a0872..0000000 --- a/www/shaders/working.glsl +++ /dev/null @@ -1,368 +0,0 @@ -// 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