+
-
-
- [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