diff --git a/.gitignore b/.gitignore index c341ed4..30c9307 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ bake/ .sass-cache/ -sandbox/ diff --git a/CREDITS.md b/CREDITS.md deleted file mode 100644 index 4896e1d..0000000 --- a/CREDITS.md +++ /dev/null @@ -1 +0,0 @@ -1. [github:rose-pine/tailwind-css](https://github.com/rose-pine/tailwind-css): I modified their css palettes diff --git a/scripts/bakeimgs b/bakeimgs similarity index 100% rename from scripts/bakeimgs rename to bakeimgs diff --git a/docs/palette.theme b/palette.theme similarity index 100% rename from docs/palette.theme rename to palette.theme diff --git a/scripts/serve b/serve similarity index 100% rename from scripts/serve rename to serve diff --git a/www/css/typing-merge.css b/www/css/typing-merge.css new file mode 100644 index 0000000..4e54f42 --- /dev/null +++ b/www/css/typing-merge.css @@ -0,0 +1,110 @@ +.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: #0e0d14; + padding: 20px; + + display: flex; + flex-direction: column; + justify-content: start; + align-content: center; + align-items: start; +} + +#typing-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 { + /* "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 { + 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; + } + 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/css/typing.css b/www/css/typing.css index 34226b2..723506b 100644 --- a/www/css/typing.css +++ b/www/css/typing.css @@ -1,3 +1,9 @@ +html, body { + height: 100%; + margin: 0; + background-color: #0e0d14; +} + .centered { position: absolute; inset: 0 0 0 0; @@ -24,7 +30,6 @@ text-align: start; border: 0.5ch solid #ffc0cb; /* #ac4aed */ - background-color: #0e0d14; padding: 20px; display: flex; @@ -79,9 +84,6 @@ width: 11ch; /* ignore prompt width */ visibility: visible; } - 25% { - width: 11ch; - } to { visibility: visible; } @@ -110,4 +112,3 @@ visibility: visible; } } - diff --git a/www/index.html b/www/index.html index f8308c9..700e299 100644 --- a/www/index.html +++ b/www/index.html @@ -9,9 +9,9 @@ - + - + diff --git a/www/index.html.bak b/www/index.html.bak new file mode 100644 index 0000000..a8d3f1c --- /dev/null +++ b/www/index.html.bak @@ -0,0 +1,38 @@ + + + + + + + + +
+
+ +
+ 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/draw-scene.js b/www/js/draw-scene.js new file mode 100644 index 0000000..0df76cc --- /dev/null +++ b/www/js/draw-scene.js @@ -0,0 +1,60 @@ +function drawScene(gl, programInfo, buffers, time) { + // Tell WebGL how to convert from clip space to pixels + gl.viewport(0, 0, gl.canvas.width, gl.canvas.height); + + gl.clearColor(0.0, 0.0, 0.0, 1.0); // Clear to black, fully opaque + gl.clearDepth(1.0); // Clear everything + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + // NOTE: this is how width/height is taken + // const aspect = gl.canvas.clientWidth / gl.canvas.clientHeight; + + // Tell WebGL how to pull out the positions from the position + // buffer into the vertexPosition attribute. + setPositionAttribute(gl, buffers, programInfo); + + gl.useProgram(programInfo.program); + + /* --- Set Uniform Variables --- */ + // Time since page loaded in seconds + gl.uniform1f( + programInfo.uniformLocations.time, + time, + ); + // Viewport resolution in pixels + gl.uniform2f( + programInfo.uniformLocations.resolution, + gl.canvas.width, + gl.canvas.height, + ); + + { + const offset = 0; + const vertexCount = 4; + gl.drawArrays(gl.TRIANGLE_STRIP, offset, vertexCount); + } +} + +// Tell WebGL how to pull out the positions from the position +// buffer into the vertexPosition attribute. +function setPositionAttribute(gl, buffers, programInfo) { + const numComponents = 2; // pull out 2 values per iteration + const type = gl.FLOAT; // the data in the buffer is 32bit floats + const normalize = false; // don't normalize + const stride = 0; // how many bytes to get from one set of values to the next + // 0 = use type and numComponents above + const offset = 0; // how many bytes inside the buffer to start from + gl.bindBuffer(gl.ARRAY_BUFFER, buffers.position); + gl.vertexAttribPointer( + programInfo.attribLocations.vertexPosition, + numComponents, + type, + normalize, + stride, + offset, + ); + gl.enableVertexAttribArray(programInfo.attribLocations.vertexPosition); +} + +export { drawScene }; + diff --git a/www/js/init-buffers.js b/www/js/init-buffers.js new file mode 100644 index 0000000..bf12c1a --- /dev/null +++ b/www/js/init-buffers.js @@ -0,0 +1,34 @@ +function initBuffers(gl) { + const positionBuffer = initPositionBuffer(gl); + + return { + position: positionBuffer, + }; +} + +function initPositionBuffer(gl) { + // Position array of a "full-screen" quad (encoded as TRIANGLE_STRIP) + // Ref: https://en.wikipedia.org/wiki/Triangle_strip + // NOTE: +x,+y is top-right & -x,-y is bottom-left + const positions = [ + -1.0, 1.0, + -1.0, -1.0, + 1.0, 1.0, + 1.0, -1.0, + ]; + + // Create a buffer for the square's positions. + const positionBuffer = gl.createBuffer(); + // Select the positionBuffer as the one to apply buffer + // operations to from here out. + gl.bindBuffer(gl.ARRAY_BUFFER, positionBuffer); + // Now pass the list of positions into WebGL to build the + // shape. We do this by creating a Float32Array from the + // JavaScript array, then use it to fill the current buffer. + gl.bufferData(gl.ARRAY_BUFFER, new Float32Array(positions), gl.STATIC_DRAW); + + return positionBuffer; +} + +export { initBuffers }; + diff --git a/www/js/main.js b/www/js/main.js deleted file mode 100644 index a5ca67b..0000000 --- a/www/js/main.js +++ /dev/null @@ -1,32 +0,0 @@ -import { Smc } from "./smc/smc.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 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) - .setMaxFps(30) - .setProgram(builder => - builder - .addFragmentShader(frag)) - .run() - ); -} - diff --git a/www/js/smc/README.md b/www/js/smc/README.md deleted file mode 100644 index c013131..0000000 --- a/www/js/smc/README.md +++ /dev/null @@ -1,4 +0,0 @@ -# Shade My Canvas -An easy to use and purely declarative wrapper for WebGL written in Javascript. -The main idea is to remove all the boilerplate required to render shader -programs, so you can focus on writing GLSL and not debugging WebGL. diff --git a/www/js/smc/errors.js b/www/js/smc/errors.js deleted file mode 100644 index 3900885..0000000 --- a/www/js/smc/errors.js +++ /dev/null @@ -1,10 +0,0 @@ -export { SmcErr }; - -const SmcErr = { - UNSUPPORTED: 0, // unused - SHADER_COMPILATION: 1, - PROGRAM_INIT: 2, - ATTRIBUTE_MISSING: 3, - UNIFORM_MISSING: 4, - FETCH_SHADER: 5, -} diff --git a/www/js/smc/lib.js b/www/js/smc/lib.js deleted file mode 100644 index cbff55e..0000000 --- a/www/js/smc/lib.js +++ /dev/null @@ -1,4 +0,0 @@ -import { Smc } from "./smc.js"; -import { SmcErr } from "./errors.js"; - -export { Smc, SmcErr }; diff --git a/www/js/smc/progbuilder.js b/www/js/smc/progbuilder.js deleted file mode 100644 index 6084410..0000000 --- a/www/js/smc/progbuilder.js +++ /dev/null @@ -1,133 +0,0 @@ -import { SmcErr } from './errors.js'; - -export { SmcProgramBuilder }; - -class SmcProgramBuilder { - #gl; - #program; - - #isBuilt = false; - #hasVertexShader = false; - #hasFragmentShader = false; - - #defaultVertexShader = ` - attribute vec4 aVertex; - - void main() { - gl_Position = aVertex; - } - `; - - // TODO: reset the sample fragment shader back to the rainbow - #sampleFragmentShader = ` - 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(216. * maxuv, 43., 72., 255.) / 255.; - - - // vec3 col = 0.5 + 0.5*cos(uv.xyx+vec3(0,2,4)); - // gl_FragColor = vec4(col, 1.); - } - `; - - - constructor(gl, raiseError) { - this.#gl = gl; - this.#program = this.#gl.createProgram(); - this.raiseError = raiseError; - } - - addVertexShader(source) { - this.#gl.attachShader( - this.#program, - this.#newShader( - this.#gl.VERTEX_SHADER, - source - ) - ) - this.#hasVertexShader = true; - return this; - } - - addFragmentShader(source) { - this.#gl.attachShader( - this.#program, - this.#newShader( - this.#gl.FRAGMENT_SHADER, - source - ) - ) - console.log(source) - this.#hasFragmentShader = true; - return this; - } - - // fetchVertexShader(uri) { - // (async () => this.#fetchShader(uri, (source) => this.addVertexShader(source)))(); - // return this; - // } - - // async fetchFragmentShader(uri) { - // var delegate = (source) => this.addFragmentShader(source); - // var source = await this.#fetchShader(uri); - // return this; - // } - - build() { - // avoid user accidental calls to build() - if (!this.#isBuilt) { - if (!this.#hasVertexShader) - this.addVertexShader(this.#defaultVertexShader) - if (!this.#hasFragmentShader) - this.addFragmentShader(this.#sampleFragmentShader); - - this.#gl.linkProgram(this.#program); - this.#gl.useProgram(this.#program); - } - return this.#program; - } - - // Creates a shader of the given type, uploads the source and compiles - #newShader(type, source) { - const shader = this.#gl.createShader(type); - this.#gl.shaderSource(shader, source); - this.#gl.compileShader(shader); - - if (!this.#gl.getShaderParameter(shader, this.#gl.COMPILE_STATUS)) { - this.#gl.deleteShader(shader); - const infoLog = this.#gl.getShaderInfoLog(shader); - this.raiseError( - SmcErr.SHADER_COMPILATION, - new Error(`An error occurred while compiling the shader: ${infoLog}`) - ); - } - - return shader; - } - - // async #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 deleted file mode 100644 index 9829921..0000000 --- a/www/js/smc/smc.js +++ /dev/null @@ -1,293 +0,0 @@ -import { SmcErr } from "./errors.js"; -import { SmcProgramBuilder } from "./progbuilder.js"; -import { hexToRgba } from "./util.js"; - -export { Smc, UniformType }; - -const UniformType = { - Float1: 0, - Float2: 1, - Float3: 2, - Float4: 3, - Int1: 4, - Int2: 5, - Int3: 6, - Int4: 7, -}; - -class Smc { - #canvas; - #gl; - - // Position array of a "full-screen" quad (encoded as TRIANGLE_STRIP) - // Ref: https://en.wikipedia.org/wiki/Triangle_strip - // NOTE: +x,+y is top-right & -x,-y is bottom-left - #verticesFullscreen = [ - -1.0, 1.0, - -1.0, -1.0, - 1.0, 1.0, - 1.0, -1.0, - ]; - #vertices = this.#verticesFullscreen; - #attributes = new Map(); - #uniforms = new Map(); - #program = null; - #clearBitFlags; - - #maxFps; - #minDeltaTimeMs; // in milliseconds - #prevTimeMs = 0; - - #errorDelegate = (_, error) => { throw error }; - #initDelegate = (_) => { }; - #resizeDelegate = (_) => { }; - - constructor(canvas) { - this.raiseError = this.raiseError.bind(this); - this.render = this.render.bind(this); - this.renderLoop = this.renderLoop.bind(this); - // DEBUG: is this necessary - this.setAttribute = this.setAttribute.bind(this); - this.setUniform = this.setUniform.bind(this); - - this.#canvas = canvas; - this.#gl = Smc.#getWebGlContext(canvas); - // NOTE: smc.isWebGlSupported() should be queried prior - if (this.#gl == null) - throw new Error("Unable to initialize WebGL. Your browser or machine may not support it."); - - // clear the entire depth buffer when this.#gl.clear is called - this.#gl.clearDepth(1.0); - this.#clearBitFlags = this.#gl.COLOR_BUFFER_BIT | this.#gl.DEPTH_BUFFER_BIT; - // set WebGL's render context (number of pixels to draw) - this.#gl.viewport(0, 0, this.#gl.canvas.width, this.#gl.canvas.height); - - // set defaults - this.setMaxFps(30); - this.setClearColor(0., 0., 0., 255.); - } - - static #getWebGlContext(canvas) { - try { - return canvas.getContext("webgl") ?? canvas.getContext("experimental-webgl"); - } catch { - return null; - }; - } - - static isWebGlSupported() { - try { - const canvas = document.createElement('canvas'); - return !!window.WebGLRenderingContext && Smc.#getWebGlContext(canvas) != null; - } catch (e) { - return false; - } - } - - onError(delegate) { - this.#errorDelegate = delegate; - return this; - } - - onInit(delegate) { - this.#initDelegate = delegate; - return this; - } - - onResize(delegate) { - this.#resizeDelegate = delegate; - return this; - } - - setClearColorHex(color) { - color = hexToRgba(color); - if (color == null) { - // this.raiseError isn't needed because this should - // be treated as a "compilation" error not a "runtime" error - throw new Error(`setClearColorHex expects an RGB/RGBA hex value, got "${color}"`); - } - return this.setClearColor(color.r, color.g, color.b, color.a); - } - - setClearColor(r, g, b, a) { - this.#gl.clearColor(r / 255., g / 255., b / 255., a / 255.); - return this; - } - - setVertices(positions) { - this.#vertices = positions; - return this; - } - - setMaxFps(fps) { - this.#maxFps = fps; - this.#minDeltaTimeMs = fps ? 1000 / fps : null; - return this; - } - - setProgram(delegate) { - const builder = new SmcProgramBuilder(this.#gl, this.raiseError); - var result = delegate(builder); - - this.#program = result.build(); - if (!this.#gl.getProgramParameter(this.#program, this.#gl.LINK_STATUS)) { - const infoLog = this.#gl.getProgramInfoLog(this.#program); - this.raiseError( - SmcErr.PROGRAM_INIT, - new Error(`Unable to initialize the shader program: ${infoLog}`) - ) - } - - this.#addAttribute("aVertex", this.#setVerticesAttribute.bind(this)); - // DEBUG: uncomment afterwards - this.#addUniform("uResolution", UniformType.Float2, false, (_) => new Float32Array([this.#gl.canvas.width, this.#gl.canvas.height])); - this.#addUniform("uTime", UniformType.Float1); - this.#addUniform("uDelta", UniformType.Float1); - return this; - } - - run() { - this.#initDelegate() - this.setAttribute("aVertex", this.#vertices); - this.setUniform("uResolution", this.#gl.canvas.width, this.#gl.canvas.height); - - if (this.#maxFps == 0) - requestAnimationFrame(this.render) - else - requestAnimationFrame(this.renderLoop); - } - - // requestAnimationFrame requests the browser to call the renderLoop - // callback function before the next repaint. - // `time` is the milliseconds elapsed since the page loaded. - renderLoop(time) { - var delta = time - this.#prevTimeMs; - this.render(time, delta); - - setTimeout( - () => requestAnimationFrame(this.renderLoop), - Math.max(0, delta - this.#minDeltaTimeMs) - ); - this.#prevTimeMs = time; - } - - render(time, delta) { - this.setUniform("uTime", time * 0.001); - this.setUniform("uDelta", delta); - this.#gl.clear(this.#gl.COLOR_BUFFER_BIT | this.#gl.DEPTH_BUFFER_BIT); - this.#gl.drawArrays(this.#gl.TRIANGLE_STRIP, 0, this.#vertices.length / 2); - } - - #addAttribute(name, setDelegate, required = false) { - var location = this.#gl.getAttribLocation(this.#program, name); - if (location == -1) { - if (required) { - this.raiseError( - SmcErr.ATTRIBUTE_MISSING, - `Linked program missing required attribute: "${name}"` - ); - } - location = null; - } - this.#attributes.set( - name, - { - setDelegate: setDelegate, - location: location, - }); - - } - - #addUniform(name, type, setEachFrame, setCallback, required = false) { - const location = this.#gl.getUniformLocation(this.#program, name); - if (location == -1) { - if (required) { - this.raiseError( - SmcErr.UNIFORM_MISSING, - `Linked program missing required uniform: "${name}"` - ) - } - location = null; - } - - if (type == UniformType.Float1) - var uniformfv = (...values) => this.#gl.uniform1f(location, ...values); - else if (type == UniformType.Float2) - var uniformfv = (...values) => this.#gl.uniform2f(location, ...values); - else if (type == UniformType.Float3) - var uniformfv = (...values) => this.#gl.uniform3f(location, ...values); - else if (type == UniformType.Float4) - var uniformfv = (...values) => this.#gl.uniform4f(location, ...values); - else if (type == UniformType.Int1) - var uniformfv = (...values) => this.#gl.uniform1i(location, ...values); - else if (type == UniformType.Int2) - var uniformfv = (...values) => this.#gl.uniform2i(location, ...values); - else if (type == UniformType.Int3) - var uniformfv = (...values) => this.#gl.uniform3i(location, ...values); - else if (type == UniformType.Int4) - var uniformfv = (...values) => this.#gl.uniform4i(location, ...values); - else { - // this.raiseError isn't needed because this should - // be treated as a "compilation" error not a "runtime" error - throw new Error(`Expected type from enum UniformType, but got "${type}"`); - } - - // simplify function call to a single argument - this.#uniforms.set( - name, - { - setDelegate: uniformfv, - location: location, - setEachFrame: setEachFrame, - setCallback: setCallback, - } - ); - } - - #getAttributeLocation(name) { - return this.#attributes.get(name).location; - } - - #getUniformLocation(name) { - return this.#uniforms.get(name).location; - } - - setAttribute(name, ...args) { - if (this.#getAttributeLocation(name) != null) - this.#attributes.get(name).setDelegate(...args); - } - - setUniform(name, ...args) { - if (this.#getUniformLocation(name) != null) { - this.#uniforms.get(name).setDelegate(...args); - } - } - - #setVerticesAttribute(vertices) { - this.#vertices = vertices; - - const buffer = this.#gl.createBuffer(); - this.#gl.bindBuffer(this.#gl.ARRAY_BUFFER, buffer); - this.#gl.bufferData( - this.#gl.ARRAY_BUFFER, - new Float32Array(vertices), - this.#gl.STATIC_DRAW - ); - - this.#gl.vertexAttribPointer( - this.#getAttributeLocation("aVertex"), - 2, // (size) one vertex == 2 floats - this.#gl.FLOAT, // (type) vertex positions given as 32bit floats - false, // (normalized) don't normalize - 0, // (stride) buffer offset pointer BETWEEN elements (0 => packed) - 0, // (offset) buffer offset pointer from START to first element - ) - this.#gl.enableVertexAttribArray(this.#getAttributeLocation("aVertex")); - - return buffer; - } - - raiseError(type, error) { - this.#errorDelegate(type, error); - } -} diff --git a/www/js/smc/util.js b/www/js/smc/util.js deleted file mode 100644 index a786d02..0000000 --- a/www/js/smc/util.js +++ /dev/null @@ -1,24 +0,0 @@ -export { hexToRgba, hexToRgbaNormal }; - -/* Converts a string of the form "#XXXXXX" - * -*/ -function hexToRgba(hex) { - var result = /^#?([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})([a-f\d]{2})?$/i.exec(hex.toLowerCase()); - return result ? { - r: parseInt(result[1], 16), - g: parseInt(result[2], 16), - b: parseInt(result[3], 16), - a: result.length == 4 ? parseInt(result[4], 16) : 255., - } : null; -} - -function hexToRgbaNormal(hex) { - var result = hexToRgba(hex); - return result ? { - r: result.r / 255., - g: result.g / 255., - b: result.b / 255., - a: result.a / 255., - } : null; -} diff --git a/www/js/webgl-demo.js b/www/js/webgl-demo.js new file mode 100644 index 0000000..5e58854 --- /dev/null +++ b/www/js/webgl-demo.js @@ -0,0 +1,136 @@ +import { initBuffers } from "./init-buffers.js"; +import { drawScene } from "./draw-scene.js"; + +main(); + +// Initialize a shader program, so WebGL knows how to draw our data +function initShaderProgram(gl, vsSource, fsSource) { + const vertexShader = loadShader(gl, gl.VERTEX_SHADER, vsSource); + const fragmentShader = loadShader(gl, gl.FRAGMENT_SHADER, fsSource); + + // Create the shader program + const program = gl.createProgram(); + gl.attachShader(program, vertexShader); + gl.attachShader(program, fragmentShader); + gl.linkProgram(program); + + // If creating the shader program failed, alert + if (!gl.getProgramParameter(program, gl.LINK_STATUS)) { + alert( + `Unable to initialize the shader program: ${gl.getProgramInfoLog( + program, + )}`, + ); + return null; + } + + return program; +} + +// Creates a shader of the given type, uploads the source and compiles +function loadShader(gl, type, source) { + const shader = gl.createShader(type); + + // Send the source to the shader object + gl.shaderSource(shader, source); + + // Compile the shader program + gl.compileShader(shader); + + // See if it compiled successfully + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + gl.deleteShader(shader); + throw new Error(`An error occurred compiling the shaders: ${gl.getShaderInfoLog(shader)}`); + } + + return shader; +} + +function renderShader(gl, vsSource, fsSource) { + const shaderProgram = initShaderProgram(gl, vsSource, fsSource); + + // Collect all the info needed to use the shader program. + // Look up which attribute our shader program is using + // for aVertexPosition and look up uniform locations. + const programInfo = { + program: shaderProgram, + attribLocations: { + vertexPosition: gl.getAttribLocation(shaderProgram, "aVertexPosition"), + }, + uniformLocations: { + resolution: gl.getUniformLocation(shaderProgram, "u_resolution"), + time: gl.getUniformLocation(shaderProgram, "u_time"), + }, + }; + + // Here's where we call the routine that builds all the + // objects we'll be drawing. + const buffers = initBuffers(gl); + + // Draw the scene + // drawScene(gl, programInfo, buffers, 0); + + const fpsLimit = 30; + const fpsDelta = 1000 / 30; + // let timePrev = 0; + // requestAnimationFrame asks the browser to call render, + // providing the time in milliseconds since the page loaded + function render(time) { + time *= 0.001; // convert to seconds + // delta = time - timePrev; + + drawScene(gl, programInfo, buffers, time); + + setTimeout(() => requestAnimationFrame(render), fpsDelta); + } + function update() { + requestAnimationFrame(render); + } + + // XXX: TODO: read this guide it's great! https://stackoverflow.com/questions/56998225/why-is-rendering-blurred-in-webgl + // window.addEventListener('resize', render); + + requestAnimationFrame(render); + // update(); + // setInterval(update, 1000 / fpsLimit); +} + +function fetchShader(name) { + return fetch(`../shaders/${name}`) + .then(res => { + if (!res.ok) throw new Error(`Failed to load fragment shader source ${url}: ${res.status}`); + return res.text(); + }); + +} + +function main() { + const canvas = document.querySelector("#gl-canvas"); + // Initialize the GL context + const gl = canvas.getContext("webgl"); + + // XXX: TODO: use `window.addEventListener('resize', ...);` + canvas.setAttribute('width', window.innerWidth); + canvas.setAttribute('height', window.innerHeight); + + // Only continue if WebGL is available and working + if (gl === null) { + throw new Error("Unable to initialize WebGL. Your browser or machine may not support it."); + } + + // Vertex shader program + const vsSource = ` + attribute vec4 aVertexPosition; + + void main() { + gl_Position = aVertexPosition; + } + `; + + // Fetch fragment shader program + fetchShader("segfault.glsl") + .then(fsSource => { + renderShader(gl, vsSource, fsSource); + }); +} + diff --git a/www/shader.html b/www/shader.html new file mode 100644 index 0000000..fd65714 --- /dev/null +++ b/www/shader.html @@ -0,0 +1,19 @@ + + + + + + WebGL Demo + + + + + + + + + + + + + diff --git a/www/shaders/fbm.glsl b/www/shaders/fbm.glsl deleted file mode 100644 index dcb1f4d..0000000 --- a/www/shaders/fbm.glsl +++ /dev/null @@ -1,96 +0,0 @@ -// Author @patriciogv - 2015 -// http://patriciogonzalezvivo.com - -#ifdef GL_ES -precision mediump float; -#endif - -uniform vec2 uResolution; -uniform float uTime; - -float random (in vec2 _st) { - return fract(sin(dot(_st.xy, - vec2(12.9898,78.233)))* - 43758.5453123); -} - -// Based on Morgan McGuire @morgan3d -// https://www.shadertoy.com/view/4dS3Wd -float noise (in vec2 _st) { - vec2 i = floor(_st); - vec2 f = fract(_st); - - // Four corners in 2D of a tile - float a = random(i); - float b = random(i + vec2(1.0, 0.0)); - float c = random(i + vec2(0.0, 1.0)); - float d = random(i + vec2(1.0, 1.0)); - - vec2 u = f * f * (3.0 - 2.0 * f); - - return mix(a, b, u.x) + - (c - a)* u.y * (1.0 - u.x) + - (d - b) * u.x * u.y; -} - -#define NUM_OCTAVES 100 -// Brightness (0.0 - 1.0) -#define BRIGHTNESS 0.55 -#define LACUNARITY 2.0 -#define GAIN 0.5 -#define SHIFT 100.0 - -// VAR_THETA defines whether to compute -// sin/cos values at runtime or -#define VAR_THETA 0 -#define THETA 0.5 -#if (VAR_THETA == 1) -#endif - -float fbm ( in vec2 _st) { - float v = 0.0; - float a = BRIGHTNESS; - // Rotate to reduce axial bias - mat2 T = LACUNARITY * mat2(cos(THETA), sin(THETA), - -sin(THETA), cos(THETA)); - for (int i = 0; i < NUM_OCTAVES; ++i) { - _st = T * _st + SHIFT; - v += noise(_st) * a; - a *= GAIN; - } - return v; -} - -#define SCALE 3. - -void main() { - vec2 st = gl_FragCoord.xy/uResolution.xy*SCALE; - // st += st * abs(sin(uTime*0.1)*3.0); - - vec2 q = vec2( - fbm( st + 0.*uTime), - fbm( st + vec2(1.0)) - ); - - vec2 r = vec2( - fbm( st + 1.0*q + vec2(1.7,9.2)+ 0.15*uTime ), - fbm( st + 1.0*q + vec2(8.3,2.8)+ 0.126*uTime) - ); - - float f = fbm(st+r); - - vec3 color = mix(vec3(0.101961,0.619608,0.666667), - vec3(0.666667,0.666667,0.498039), - clamp((f*f)*4.0,0.0,1.0)); - - color = mix(color, - vec3(0,0,0.164706), - clamp(length(q),0.0,1.0)); - - color = mix(color, - vec3(0.666667,1,1), - clamp(length(r.x),0.0,1.0)); - - gl_FragColor = vec4((f*f*f+.6*f*f+.5*f)*color,1.); -} - diff --git a/www/shaders/optimised.glsl b/www/shaders/optimised.glsl deleted file mode 100644 index 8fd8d1b..0000000 --- a/www/shaders/optimised.glsl +++ /dev/null @@ -1,323 +0,0 @@ -/* BTW: You can use ANY function as the noise/plasma function - * It just needs to return a float in the range 0.0 - 17.0 - * But shouldn't return 0.0 or 17.0 (they're exclusive bounds). - * View this shader on shadertoy: https://www.shadertoy.com/view/t3tSRj# - */ - -// is highp wasteful for this shader? -#ifdef GL_ES -# ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -# else -precision mediump float; -# endif -#endif - -uniform float 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.) -/* ======= Text Size ======= */ -#define FONT_SIZE vec2(10.,20.) -#define ROWCOLS vec2(80., 24.) - -// =================================================================== -// Library Functions -// -float rand (in vec2 _st) { - return fract(sin(dot(_st.xy, vec2(12.9898,78.233))) * 43758.5453123); -} - -float quantise(float val, float n) { - return clamp(floor(val * n), 0.0, n) / n; -} - -float roundSquare(vec2 p, vec2 b, float r) { - return length(max(abs(p)-b,0.0))-r; -} - - -// =================================================================== -// VT220 Font Rendering -// Author/Source : https://www.shadertoy.com/view/llSXDV -// -#define l(y,a,b) roundLine(p, vec2(float(a), float(y)), vec2(float(b), float(y))) -float roundLine(vec2 p, vec2 a, vec2 b) { - b -= a + vec2(1.0,0.); - p -= a; - float f = length(p-clamp(dot(p,b)/dot(b,b),0.0,1.0)*b); - if (uResolution.y < 320.) // attempt to get rid of aliasing on small resolution - return smoothstep(1.0, 0.9, f); - else if (uResolution.y < 720.) - return smoothstep(0.75, 0.5, f); - else - return smoothstep(1., 0., f); -} - -float vt220Font(vec2 p, float c) { - if (c < 1.) return 0.; - if (p.y > 16.) { - if (c > 2.) return 0.0; - if (c > 1.) return l(17,1,9); - } - if (p.y > 14.) { - if (c > 16.) return l(15,3,8); - if (c > 15.) return l(15,1,8); - if (c > 14.) return l(15,1,3)+ l(15,7,9); - if (c > 13.) return l(15,2,8); - if (c > 12.) return l(15,1,9); - if (c > 11.) return l(15,2,8); - if (c > 10.) return l(15,1,3)+ l(15,6,8); - if (c > 9.) return l(15,4,6); - if (c > 8.) return l(15,2,4)+ l(15,5,7); - if (c > 7.) return l(15,2,8); - if (c > 6.) return l(15,2,8); - if (c > 5.) return l(15,2,8); - if (c > 4.) return l(15,2,9); - if (c > 3.) return l(15,1,8); - if (c > 2.) return l(15,2,9); - } - if (p.y > 12.) { - if (c > 16.) return l(13,2,4)+ l(13,7,9); - if (c > 15.) return l(13,2,4)+ l(13,7,9); - if (c > 14.) return l(13,1,3)+ l(13,7,9); - if (c > 13.) return l(13,1,3)+ l(13,7,9); - if (c > 12.) return l(13,1,3); - if (c > 11.) return l(13,4,6); - if (c > 10.) return l(13,2,4)+ l(13,5,9); - if (c > 9.) return l(13,2,8); - if (c > 8.) return l(13,2,4)+ l(13,5,7); - if (c > 7.) return l(13,1,3)+ l(13,7,9); - if (c > 6.) return l(13,1,3)+ l(13,7,9); - if (c > 5.) return l(13,1,3)+ l(13,7,9); - if (c > 4.) return l(13,1,3)+ l(15,2,9); - if (c > 3.) return l(13,1,4)+ l(13,7,9); - if (c > 2.) return l(13,1,3)+ l(13,6,9); - } - if (p.y > 10.) { - if (c > 16.) return l(11,1,3); - if (c > 15.) return l(11,2,4)+ l(11,7,9); - if (c > 14.) return l(11,1,9); - if (c > 13.) return l(11,7,9); - if (c > 12.) return l(11,2,5); - if (c > 11.) return l(11,4,6); - if (c > 10.) return l(11,3,5)+ l(11,6,8); - if (c > 9.) return l(11,4,6)+ l(11,7,9); - if (c > 8.) return l(11,1,8); - if (c > 7.) return l(11,1,3)+ l(11,7,9); - if (c > 6.) return l(11,1,3)+ l(11,7,9); - if (c > 5.) return l(11,1,3)+ l(11,7,9); - if (c > 4.) return l(11,1,3); - if (c > 3.) return l(11,1,3)+ l(11,7,9); - if (c > 2.) return l(11,2,9); - } - if (p.y > 8.) { - if (c > 16.) return l(9,1,3); - if (c > 15.) return l(9,2,8); - if (c > 14.) return l(9,1,3)+ l(9,7,9); - if (c > 13.) return l(9,4,8); - if (c > 12.) return l(9,4,8); - if (c > 11.) return l(9,4,6); - if (c > 10.) return l(9,4,6); - if (c > 9.) return l(9,2,8); - if (c > 8.) return l(9,2,4)+ l(9,5,7); - if (c > 7.) return l(9,1,3)+ l(9,7,9); - if (c > 6.) return l(9,1,3)+ l(9,7,9); - if (c > 5.) return l(9,1,3)+ l(9,7,9); - if (c > 4.) return l(9,1,3)+ l(9,7,9); - if (c > 3.) return l(9,1,4)+ l(9,7,9); - if (c > 2.) return l(9,7,9); - } - if (p.y > 6.) { - if (c > 16.) return l(7,1,3); - if (c > 15.) return l(7,2,4)+ l(7,7,9); - if (c > 14.) return l(7,2,4)+ l(7,6,8); - if (c > 13.) return l(7,5,7); - if (c > 12.) return l(7,7,9); - if (c > 11.) return l(7,2,6); - if (c > 10.) return l(7,2,4)+ l(7,5,7); - if (c > 9.) return l(7,1,3)+ l(7,4,6); - if (c > 8.) return l(7,1,8); - if (c > 7.) return l(7,2,8); - if (c > 6.) return l(7,2,8); - if (c > 5.) return l(7,2,8); - if (c > 4.) return l(7,2,8); - if (c > 3.) return l(7,1,8); - if (c > 2.) return l(7,2,8); - } - if (p.y > 4.) { - if (c > 16.) return l(5,2,4)+ l(5,7,9); - if (c > 15.) return l(5,2,4)+ l(5,7,9); - if (c > 14.) return l(5,3,7); - if (c > 13.) return l(5,6,8); - if (c > 12.) return l(5,1,3)+ l(5,7,9); - if (c > 11.) return l(5,3,6); - if (c > 10.) return l(5,1,5)+ l(5,6,8); - if (c > 9.) return l(5,2,8); - if (c > 8.) return l(5,2,4)+ l(5,5,7); - if (c > 7.) return 0.; - if (c > 6.) return 0.; - if (c > 5.) return 0.; - if (c > 4.) return 0.; - if (c > 3.) return l(5,1,3); - if (c > 2.) return 0.; - } - if (p.y > 2.) { - if (c > 16.) return l(3,3,8); - if (c > 15.) return l(3,1,8); - if (c > 14.) return l(3,4,6); - if (c > 13.) return l(3,1,9); - if (c > 12.) return l(3,2,8); - if (c > 11.) return l(3,4,6); - if (c > 10.) return l(3,2,4)+ l(3,7,9); - if (c > 9.) return l(3,4,6); - if (c > 8.) return l(3,2,4)+ l(3,5,7); - if (c > 7.) return l(3,2,4)+ l(3,6,8); - if (c > 6.) return l(3,1,3)+ l(3,4,7); - if (c > 5.) return l(3,2,4)+ l(3,6,8); - if (c > 4.) return 0.; - if (c > 3.) return l(3,1,3); - if (c > 2.) return 0.; - } - else { - if (c > 7.) return 0.; - if (c > 6.) return l(1,2,5)+ l(1,6,8); - } - return 0.0; -} - - -// =================================================================== -// Text Effects -// textLines(...) is for simulating the writing of random characters in line formats -// https://www.shadertoy.com/view/llSXDV (same author as VT220 font rendering) -// -float textLines(vec2 uvG) { - float wt = 5. * (uTime + 0.5*sin(uTime*1.4) + 0.2*sin(uTime*2.9)); // wobbly time - vec2 uvGt = uvG + vec2(0., floor(wt)); - float ll = rand(vec2(uvGt.y, - 1.)) * ROWCOLS.x; // line length - - if (uvG.y > ROWCOLS.y - 2.){ - if (ceil(uvG.x) == floor(min(ll, fract(wt)*ROWCOLS.x))) - return 2.; - if (ceil(uvG.x) > floor(min(ll, fract(wt)*ROWCOLS.x))) - return 0.; - } - if (uvGt.x > 5. && rand(uvGt) < .075) - return 0.; - if (max(5., uvGt.x) > ll) - return 0.; - - return rand(uvGt)*15. + 2.; -} - - -// =================================================================== -// Noise Generation Algorithms -// noise(...) is for the main noise generation algorithm (very tunable) -// https://www.shadertoy.com/view/MsdGWn -// - -// Based on Morgan McGuire @morgan3d -// https://www.shadertoy.com/view/4dS3Wd -float noise (in vec2 _st) { - vec2 i = floor(_st); - vec2 f = fract(_st); - - // Four corners in 2D of a tile - float a = rand(i); - float b = rand(i + vec2(1.0, 0.0)); - float c = rand(i + vec2(0.0, 1.0)); - float d = rand(i + vec2(1.0, 1.0)); - - vec2 u = f * f * (3.0 - 2.0 * f); - - return mix(a, b, u.x) + - (c - a)* u.y * (1.0 - u.x) + - (d - b) * u.x * u.y; -} - -#define NUM_OCTAVES 100 -// Brightness (0.0 - 1.0) -#define BRIGHTNESS 0.55 -#define LACUNARITY 2.0 -#define GAIN 0.5 -#define SHIFT 100.0 - -// VAR_THETA defines whether to compute -// sin/cos values at runtime or -#define VAR_THETA 0 -#define THETA 0.5 -#if (VAR_THETA == 1) -#endif - -float fbm( in vec2 _st) { - float v = 0.0; - float a = BRIGHTNESS; - // Rotate to reduce axial bias - mat2 T = LACUNARITY * mat2(cos(THETA), sin(THETA), - -sin(THETA), cos(THETA)); - for (int i = 0; i < NUM_OCTAVES; ++i) { - _st = T * _st + SHIFT; - v += noise(_st) * a; - a *= GAIN; - } - return v; -} - - -#define SCALE_UV 3. -#define SCALE_TIME 1. - -// XXX: TODO: use two shaders, the first on a MUCH lower resolution (one pixel for each text character) -// XXX: TODO: then the second should map those pixel values to higher resolution text characters -void main() { - vec2 uv = gl_FragCoord.xy / uResolution; - vec2 st = uv * SCALE; - - // // uvNoise = ceil(uvNoise * ROWCOLS) / ROWCOLS; - // float val = noise(st); - // // Noise is fed through a sigmoid function, then quantised to integer range 0-17 - // val = (exp(val) / 2.71828); // increase contrast (normalised 0.0 - 1.0) - // val = 1.0 / val; - // val *= 1.0 / (1.0 + exp(-val)) - 0.5; // subtraction value is tunable (range 0.0 - 0.5) - // val *= quantise(val, 17.0); // quantise by 17 then normalise back to 0.0 - 1.0 - // val = pow(18.0, val) - 1.0; // TODO: try changing 18.0 to 200.0 and you'll notice some pretty changes :) - - // // VT220 Font Rendering - // vec2 base = uv; - // base.y = 1 - base.y; - // vec2 uvT = ROWCOLS * FONT_SIZE * base; - // vec2 uvG = floor(ROWCOLS * base; - // gl_FragColor = vt220Font(uvT - uvG * FONT_SIZE, val) * PHOSPHOR_COL + BG_COL; - - vec2 q = vec2( - fbm( st + 0.*uTime), - fbm( st + vec2(1.0)) - ); - - vec2 r = vec2( - fbm( st + 1.0*q + vec2(1.7,9.2)+ 0.15*uTime ), - fbm( st + 1.0*q + vec2(8.3,2.8)+ 0.126*uTime) - ); - - float f = fbm(st+r); - - vec3 color = mix(vec3(0.101961,0.619608,0.666667), - vec3(0.666667,0.666667,0.498039), - clamp((f*f)*4.0,0.0,1.0)); - - color = mix(color, - vec3(0,0,0.164706), - clamp(length(q),0.0,1.0)); - - color = mix(color, - vec3(0.666667,1,1), - clamp(length(r.x),0.0,1.0)); - - gl_FragColor = vec4((f*f*f+.6*f*f+.5*f)*color,1.); -} - 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..a3d73a8 100644 --- a/www/shaders/segfault.glsl +++ b/www/shaders/segfault.glsl @@ -11,13 +11,13 @@ precision mediump float; #endif -uniform float uTime; -uniform vec2 uResolution; +uniform float u_time; +uniform vec2 u_resolution; /* ==== Text Colouring ==== */ -#define PHOSPHOR_COL vec4(196./255., 167./255., 231./255., 1.) +#define PHOSPHOR_COL vec4(1, 1., 1., 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 BG_COL vec4(0.0, 0.0, 0.0, 1.) /* ======= Text Size ======= */ #define FONT_SIZE vec2(10.,20.) #define ROWCOLS vec2(80., 24.) @@ -155,9 +155,9 @@ 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 (uResolution.y < 320.) // attempt to get rid of aliasing on small resolution + if (u_resolution.y < 320.) // attempt to get rid of aliasing on small resolution return smoothstep(1.0, 0.9, f); - else if (uResolution.y < 720.) + else if (u_resolution.y < 720.) return smoothstep(0.75, 0.5, f); else return smoothstep(1., 0., f); @@ -305,7 +305,7 @@ float vt220Font(vec2 p, float c) { // https://www.shadertoy.com/view/MsdGWn // float textLines(vec2 uvG) { - float wt = 5. * (uTime + 0.5*sin(uTime*1.4) + 0.2*sin(uTime*2.9)); // wobbly time + float wt = 5. * (u_time + 0.5*sin(u_time*1.4) + 0.2*sin(u_time*2.9)); // wobbly time vec2 uvGt = uvG + vec2(0., floor(wt)); float ll = rand(vec2(uvGt.y, - 1.)) * ROWCOLS.x; // line length @@ -351,21 +351,21 @@ float smokeNoise(vec3 v) { } void main() { - vec2 uv = vec2(gl_FragCoord.x, uResolution.y - gl_FragCoord.y); - vec2 uvT = ROWCOLS * FONT_SIZE * uv / uResolution.xy; - vec2 uvG = floor(ROWCOLS * uv / uResolution.xy); - vec2 uvC = gl_FragCoord.xy / uResolution.xy; + vec2 uv = vec2(gl_FragCoord.x, u_resolution.y - gl_FragCoord.y); + vec2 uvT = ROWCOLS * FONT_SIZE * uv / u_resolution.xy; + vec2 uvG = floor(ROWCOLS * uv / u_resolution.xy); + vec2 uvC = gl_FragCoord.xy / u_resolution.xy; - vec2 uvNoise = gl_FragCoord.xy / uResolution.xy; + vec2 uvNoise = gl_FragCoord.xy / u_resolution.xy; uvNoise = ceil(uvNoise * ROWCOLS) / ROWCOLS; float val; - if (uTime < 2.0) + if (u_time < 2.0) val = textLines(uvG); - else if (uTime < 2.3) - val = rand(uvG * uTime) * 17.; + else if (u_time < 2.3) + val = rand(uvG * u_time) * 17.; else { - float noise = smokeNoise(vec3(uvNoise * noiseScale, uTime * noiseTimeScale)); + float noise = smokeNoise(vec3(uvNoise * noiseScale, u_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; diff --git a/www/shaders/squares.glsl b/www/shaders/squares.glsl deleted file mode 100644 index 3520ecc..0000000 --- a/www/shaders/squares.glsl +++ /dev/null @@ -1,50 +0,0 @@ -// is highp wasteful for this shader? -#ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; -#else -precision mediump float; -#endif - -uniform float uTime; -uniform vec2 uResolution; - -#define ROWS 10. - -float rand(in vec2 _st) { - return fract(sin(dot(_st.xy, vec2(12.9898,78.233))) * 43758.5453123); -} - -// #define STEPS 10. - -void main() { - // float ROWS = mod(uTime, 2. * STEPS); - - float aspect = uResolution.x / uResolution.y; - float cols = floor(ROWS * aspect); - - vec2 uv = vec2( - ceil(gl_FragCoord.x / uResolution.x * cols) / cols, - ceil(gl_FragCoord.y / uResolution.y * ROWS) / ROWS - ); - // vec2 uv = ceil(gl_FragCoord.xy / uResolution * vec2(ROWS, COLS)) / vec2(ROWS, COLS); - - float offset = rand(uv) + rand(vec2(uTime, uTime)); - float id = mod(abs(uv.y * ROWS + uv.x * cols + offset), 4.); // project f(t) = (1, 1)t + uv against the y-axis - vec3 col = vec3(255., 0., 0.) / 255.; - if (id < 1.) { - col = vec3(156., 207., 216.) / 255.; - } else if (id < 2.) { - col = vec3(246., 193., 119.) / 255.; - } else if (id < 3.) { - col = vec3(196., 167., 231.) / 255.; - } else if (id < 4.) { - col = vec3(235., 111., 146.) / 255.; - } - // vec3 col = vec3(id, id, id); - - // float val1 = rand(uv); - // float val2 = rand(val1 + uv); - // float val3 = rand(val2 + uv); - // vec3 col = vec3(val1, val2, val3); - gl_FragColor = vec4(col,1.0); -} diff --git a/www/shaders/trivial.glsl b/www/shaders/trivial.glsl index 9935c91..22464ae 100644 --- a/www/shaders/trivial.glsl +++ b/www/shaders/trivial.glsl @@ -1,17 +1,17 @@ // is highp wasteful for this shader? #ifdef GL_FRAGMENT_PRECISION_HIGH -precision highp float; + precision highp float; #else -precision mediump float; + precision mediump float; #endif -uniform float uTime; -uniform vec2 uResolution; +uniform float u_time; +uniform vec2 u_resolution; void main() { - vec2 uv = gl_FragCoord.xy / uResolution; + vec2 uv = gl_FragCoord.xy / u_resolution; - vec3 col = 0.5 + 0.5 * cos(uTime + uv.xyx + vec3(0, 2, 4)); + vec3 col = 0.5 + 0.5 * cos(u_time + uv.xyx + vec3(0, 2, 4)); gl_FragColor = vec4(col,1.0); } 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