Compare commits
No commits in common. "c21e84391c4264a5d215a29020c7aacda1f8ac8f" and "dc2ec07b0aa5a31c959fe4f352b35b381e6f079c" have entirely different histories.
c21e84391c
...
dc2ec07b0a
15 changed files with 573 additions and 327 deletions
|
|
@ -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 <br/> */
|
|
||||||
}
|
|
||||||
|
|
||||||
.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 {
|
|
||||||
}
|
|
||||||
11
www/css/shader-style.css
Normal file
11
www/css/shader-style.css
Normal file
|
|
@ -0,0 +1,11 @@
|
||||||
|
.gl-canvas-bg {
|
||||||
|
display:block;
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
|
||||||
|
position: fixed;
|
||||||
|
left: 0;
|
||||||
|
top: 0;
|
||||||
|
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
|
@ -1,27 +1,3 @@
|
||||||
body {
|
body {
|
||||||
background-color: var(--theme-bg);
|
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;
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -1,15 +1,11 @@
|
||||||
.theme-base {
|
.theme-tty-base {
|
||||||
color: var(--theme-base);
|
color: var(--theme-base);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-bg {
|
.theme-tty-bg {
|
||||||
color: var(--theme-bg);
|
color: var(--theme-bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-text {
|
|
||||||
color: var(--theme-text);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-tty-prompt {
|
.theme-tty-prompt {
|
||||||
color: var(--theme-tty-prompt);
|
color: var(--theme-tty-prompt);
|
||||||
}
|
}
|
||||||
|
|
@ -18,10 +14,6 @@
|
||||||
color: var(--theme-tty-command);
|
color: var(--theme-tty-command);
|
||||||
}
|
}
|
||||||
|
|
||||||
.theme-tty-output {
|
|
||||||
color: var(--theme-tty-output);
|
|
||||||
}
|
|
||||||
|
|
||||||
.theme-tty-warning {
|
.theme-tty-warning {
|
||||||
color: var(--theme-tty-warning);
|
color: var(--theme-tty-warning);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -20,12 +20,9 @@ Variables:
|
||||||
:root {
|
:root {
|
||||||
--theme-base: var(--palette-rose-pine-base);
|
--theme-base: var(--palette-rose-pine-base);
|
||||||
--theme-bg: 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-prompt: var(--palette-rose-pine-foam);
|
||||||
--theme-tty-command: var(--palette-rose-pine-iris);
|
--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-warning: var(--palette-rose-pine-gold);
|
||||||
--theme-tty-error: var(--palette-rose-pine-love);
|
--theme-tty-error: var(--palette-rose-pine-love);
|
||||||
/* --theme-tty-: var(--palette-rose-pine-); */
|
/* --theme-tty-: var(--palette-rose-pine-); */
|
||||||
|
|
|
||||||
118
www/css/typing.css
Normal file
118
www/css/typing.css
Normal file
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -12,54 +12,42 @@
|
||||||
|
|
||||||
<!-- Styling -->
|
<!-- Styling -->
|
||||||
<link type="text/css" rel="stylesheet" href="css/style.css">
|
<link type="text/css" rel="stylesheet" href="css/style.css">
|
||||||
<link type="text/css" rel="stylesheet" href="css/ppty.css">
|
<link type="text/css" rel="stylesheet" href="css/shader-style.css">
|
||||||
|
<link type="text/css" rel="stylesheet" href="css/typing.css">
|
||||||
</head>
|
</head>
|
||||||
|
|
||||||
<body>
|
<body>
|
||||||
<!-- ShadeMyCanvas (background) -->
|
<canvas class="gl-canvas-bg" id="gl-canvas"></canvas>
|
||||||
<canvas id="bg-canvas"></canvas>
|
|
||||||
|
|
||||||
<!-- Psuedo-Pseudo-Terminal -->
|
|
||||||
<div class="centered heading">
|
|
||||||
<div class="ppty" id="boot-ppty">
|
|
||||||
|
|
||||||
<div class="ppty-block">
|
<div class="centered heading">
|
||||||
<div class="ppty-prompt">
|
<div id="typing-wrapper">
|
||||||
grub>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ppty-command">
|
|
||||||
boot
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ppty-output theme-tty-warning">
|
|
||||||
ERROR: Root device mounted successfully, but /sbin/init does not exist.<br/><br/>
|
|
||||||
|
|
||||||
<i class="theme-tty-error">
|
|
||||||
Bailing out, you are on your own.<br/>
|
|
||||||
Good luck<br/><br/>
|
|
||||||
</i>
|
|
||||||
|
|
||||||
sh: can't access tty; job control turned off<br/><br/>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ppty-block">
|
<div id="typing-prompt">
|
||||||
<div class="ppty-prompt">
|
grub> <span class="theme-tty-command">boot</span>
|
||||||
[rootfs ]#
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ppty-command">
|
|
||||||
do butterflies cry when they're sad?
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="ppty-output">
|
|
||||||
<i class="theme-tty-error">
|
|
||||||
Segmentation fault (core dumped)
|
|
||||||
</i>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div id="typing-result"> <!-- class="theme-tty-warning"> -->
|
||||||
|
ERROR: Root device mounted successfully, but /sbin/init does not exist.<br/><br/>
|
||||||
|
|
||||||
|
<i class="theme-tty-error">
|
||||||
|
Bailing out, you are on your own.<br/>
|
||||||
|
Good luck
|
||||||
|
</i><br/><br/>
|
||||||
|
|
||||||
|
sh: can't access tty; job control turned off<br/><br/>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div id="typing-prompt-segfault">
|
||||||
|
[rootfs ]# <span class="theme-tty-command">do butterflies cry when they're sad?</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div id="typing-result-segfault">
|
||||||
|
<i class="theme-tty-error">
|
||||||
|
Segmentation fault (core dumped)
|
||||||
|
</i>
|
||||||
|
</div>
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,59 +1,24 @@
|
||||||
import { Smc, fetchShader } from "./smc/lib.js";
|
import { Smc } from "./smc/smc.js"
|
||||||
import { PPTY } from "./ppty/lib.js";
|
|
||||||
|
|
||||||
main();
|
main();
|
||||||
|
|
||||||
function endBoot(root) {
|
async function fetchShader(uri, delegate) {
|
||||||
const style = getComputedStyle(root);
|
const res = await fetch(uri);
|
||||||
const paddingLeft = parseFloat(style.paddingLeft);
|
if (res.ok)
|
||||||
const paddingRight = parseFloat(style.paddingRight);
|
return await res.text();
|
||||||
const contentWidth = root.clientWidth - paddingLeft - paddingRight;
|
this.raiseError(
|
||||||
const paddingTop = parseFloat(style.paddingTop);
|
SmcErr.FETCH_SHADER,
|
||||||
const paddingBottom = parseFloat(style.paddingBottom);
|
`Failed to load shader source ${url}: ${res.status} ${res.json()}`);
|
||||||
const contentHeight = root.clientHeight - paddingTop - paddingBottom;
|
return ""
|
||||||
|
|
||||||
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 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('width', window.innerWidth);
|
||||||
canvas.setAttribute('height', window.innerHeight);
|
canvas.setAttribute('height', window.innerHeight);
|
||||||
|
|
||||||
|
|
||||||
fetchShader("../shaders/segfault.glsl")
|
fetchShader("../shaders/segfault.glsl")
|
||||||
.then(frag =>
|
.then(frag =>
|
||||||
new Smc(canvas)
|
new Smc(canvas)
|
||||||
|
|
|
||||||
|
|
@ -1,2 +0,0 @@
|
||||||
import { PPTY } from "./ppty.js";
|
|
||||||
export { PPTY };
|
|
||||||
|
|
@ -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);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -1,14 +1,4 @@
|
||||||
import { Smc } from "./smc.js";
|
import { Smc } from "./smc.js";
|
||||||
import { SmcErr } from "./errors.js";
|
import { SmcErr } from "./errors.js";
|
||||||
|
|
||||||
export { Smc, SmcErr, fetchShader };
|
export { Smc, SmcErr };
|
||||||
|
|
||||||
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 ""
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -164,11 +164,10 @@ class Smc {
|
||||||
var delta = time - this.#prevTimeMs;
|
var delta = time - this.#prevTimeMs;
|
||||||
this.render(time, delta);
|
this.render(time, delta);
|
||||||
|
|
||||||
requestAnimationFrame(this.renderLoop);
|
setTimeout(
|
||||||
// setTimeout(
|
() => requestAnimationFrame(this.renderLoop),
|
||||||
// () => requestAnimationFrame(this.renderLoop),
|
Math.max(0, delta - this.#minDeltaTimeMs)
|
||||||
// Math.max(0, delta - this.#minDeltaTimeMs)
|
);
|
||||||
// );
|
|
||||||
this.#prevTimeMs = time;
|
this.#prevTimeMs = time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
23
www/shaders/sample.glsl
Normal file
23
www/shaders/sample.glsl
Normal file
|
|
@ -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.);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -15,8 +15,9 @@ uniform float uTime;
|
||||||
uniform vec2 uResolution;
|
uniform vec2 uResolution;
|
||||||
|
|
||||||
/* ==== Text Colouring ==== */
|
/* ==== Text Colouring ==== */
|
||||||
#define PHOSPHOR_COL vec4(224./255., 222./255., 244./255., 1.)
|
#define PHOSPHOR_COL vec4(196./255., 167./255., 231./255., 1.)
|
||||||
#define BG_COL vec4(24./255., 23./255., 30./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 ======= */
|
/* ======= Text Size ======= */
|
||||||
#define FONT_SIZE vec2(10.,20.)
|
#define FONT_SIZE vec2(10.,20.)
|
||||||
#define ROWCOLS vec2(80., 24.)
|
#define ROWCOLS vec2(80., 24.)
|
||||||
|
|
|
||||||
368
www/shaders/working.glsl
Normal file
368
www/shaders/working.glsl
Normal file
|
|
@ -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<noiseSwirlSteps; i++) {
|
||||||
|
v.xy += vec2(fbm3(v), fbm3(vec3(v.xy, v.z + 1000.))) * noiseSwirlStepValue;
|
||||||
|
}
|
||||||
|
// normalize
|
||||||
|
return fbm5(v) / 2. + 0.5;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec2 uv = vec2(gl_FragCoord.x, resolution.y - gl_FragCoord.y);
|
||||||
|
vec2 uvT = ROWCOLS * FONT_SIZE * uv / resolution.xy;
|
||||||
|
vec2 uvG = floor(ROWCOLS * uv / resolution.xy);
|
||||||
|
vec2 uvC = gl_FragCoord.xy / resolution;
|
||||||
|
|
||||||
|
vec2 uvNoise = uvC;
|
||||||
|
uvNoise = ceil(uvNoise * ROWCOLS) / ROWCOLS;
|
||||||
|
|
||||||
|
float val;
|
||||||
|
if (time < 2.0)
|
||||||
|
val = textLines(uvG);
|
||||||
|
else if (time < 2.3)
|
||||||
|
val = rand(uvG * time) * 17.;
|
||||||
|
else {
|
||||||
|
float noise = smokeNoise(vec3(uvNoise * noiseScale, time * noiseTimeScale));
|
||||||
|
// Noise is fed through a sigmoid function, then quantised to integer range 0-17
|
||||||
|
val = (exp(noise) / 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 :)
|
||||||
|
}
|
||||||
|
|
||||||
|
gl_FragColor = vt220Font(uvT - uvG * FONT_SIZE, val) * PHOSPHOR_COL + BG_COL;
|
||||||
|
}
|
||||||
Loading…
Add table
Add a link
Reference in a new issue