From 8cbe93d74da8e0c07fa197dddef63629b3a7a8cb Mon Sep 17 00:00:00 2001 From: Noelle Calliope <1581674+mekanoe@users.noreply.github.com> Date: Sun, 1 Oct 2023 17:56:34 -0400 Subject: [PATCH] add 002 --- README.md | 3 ++ generators/README.md.txt | 2 + generators/generate.ts | 8 +++- html/002-rainbow-trinity.html | 31 +++++++++++++++ html/002-rainbow-trinity.js | 74 +++++++++++++++++++++++++++++++++++ html/index.html | 1 + html/lib/shader.js | 34 ++++++++++++++++ package.json | 2 +- 8 files changed, 152 insertions(+), 3 deletions(-) create mode 100644 html/002-rainbow-trinity.html create mode 100644 html/002-rainbow-trinity.js diff --git a/README.md b/README.md index b3623dc..882a947 100644 --- a/README.md +++ b/README.md @@ -9,6 +9,7 @@ https://art.mekanoe.com ## Artworks - [./001-platform-provenance](https://art.mekanoe.com/001-platform-provenance) +- [./002-rainbow-trinity](https://art.mekanoe.com/002-rainbow-trinity) ## Development @@ -18,6 +19,8 @@ https://art.mekanoe.com `bun serve` to serve them locally +`bun dev` if you're developing the templates for auto-generation. + ### Infrastructure - The "generator" does diff --git a/generators/README.md.txt b/generators/README.md.txt index 9a969b2..86964da 100644 --- a/generators/README.md.txt +++ b/generators/README.md.txt @@ -18,6 +18,8 @@ https://art.mekanoe.com `bun serve` to serve them locally +`bun dev` if you're developing the templates for auto-generation. + ### Infrastructure - The "generator" does diff --git a/generators/generate.ts b/generators/generate.ts index b5022ef..f5aee09 100644 --- a/generators/generate.ts +++ b/generators/generate.ts @@ -13,7 +13,8 @@ for (const htmlFile of allHtmls) { const allWorks = globSync("html/*.js") .map((file) => file.replace("html/", "").replace(".js", "")) - .filter((work) => work !== "platform"); + .sort() + .reverse(); console.log({ allWorks }); @@ -25,13 +26,16 @@ for (const work of allWorks) { const index = indexTemplate.replace( "", - allWorks.map((work) => `
  • ./${work}
  • `).join("\n") + allWorks + .map((work) => `
  • ./${work}
  • `) + .join("\n ") ); await Bun.write("html/index.html", index); const readme = readmeTemplate.replace( "", allWorks + .reverse() .map((work) => `- [./${work}](https://art.mekanoe.com/${work})`) .join("\n") ); diff --git a/html/002-rainbow-trinity.html b/html/002-rainbow-trinity.html new file mode 100644 index 0000000..e43e463 --- /dev/null +++ b/html/002-rainbow-trinity.html @@ -0,0 +1,31 @@ + + +com.mekanoe.art // 002-rainbow-trinity + + +
    + +
    XX.X FPS (XX.X ms)
    +
    + + diff --git a/html/002-rainbow-trinity.js b/html/002-rainbow-trinity.js new file mode 100644 index 0000000..1402215 --- /dev/null +++ b/html/002-rainbow-trinity.js @@ -0,0 +1,74 @@ +import { Shader, colorUtils, commonFrag, commonVert } from "./lib/shader.js"; +import { BasicPlane } from "./lib/basic-plane.js"; +import { App } from "./lib/app.js"; + +const app = new App({ fov: 20 }); +const gl = app.gl; + +const shader = new Shader(app) + .attach( + gl.VERTEX_SHADER, + ` + ${commonVert} + + varying highp vec2 vTextureCoord; + + void main() { + gl_Position = uProjectionMatrix * uModelViewMatrix * aVertexPosition; + vTextureCoord = aTextureCoord; + } + ` + ) + .attach( + gl.FRAGMENT_SHADER, + ` + ${commonFrag} + ${colorUtils} + + varying highp vec2 vTextureCoord; + + vec3 circle(vec2 pos, vec3 color) { + float radius = 0.75; + float dist = length(pos); + float circle = smoothstep(radius + 0.001, radius, dist); + return color * vec3(1.0 - circle); + } + + vec3 colorRotator(vec3 color, float phase, vec2 uv) { + color.x += uSinTime * 0.0001 + uv.y; + vec3 hsv = rgb2hsv(color); + hsv.x += uSinTime * 0.001 * uv.y - phase; + hsv.y = 1.0; + hsv.z = 0.5; + vec3 rgb = hsv2rgb(hsv); + return rgb; + } + + void main() { + float value = sin(uTime * 0.00025) * 0.5 + 0.5; + vec2 sv = vec2(1.0, 1.0); + vec3 triUpper = hsv2rgb(vec3(value, sv)); + vec3 triLeft = hsv2rgb(vec3(value + 0.33, sv)); + vec3 triRight = hsv2rgb(vec3(value + 0.66, sv)); + + vec2 uv = vTextureCoord * 2.0 - 1.0; + vec3 color = vec3(0.0); + + // place 3 circles in a triangle + color += circle(vec2(uv.x, uv.y + 0.5), colorRotator(triUpper, 1.0, uv)); + color += circle(vec2(uv.x - 0.5, uv.y - 0.33), colorRotator(triLeft, 0.667, uv)); + color += circle(vec2(uv.x + 0.5, uv.y - 0.33), colorRotator(triRight, 0.333, uv)); + + // color = 1.0 - color; + + gl_FragColor = vec4(color, 1.0); + gl_FragColor = clamp(gl_FragColor, 0.0, 1.0); + } + ` + ) + .link(); + +const plane = new BasicPlane(app); +plane.attachShader(shader); + +app.loop(); diff --git a/html/index.html b/html/index.html index 6c689b6..f78e35d 100644 --- a/html/index.html +++ b/html/index.html @@ -30,6 +30,7 @@
    diff --git a/html/lib/shader.js b/html/lib/shader.js index 701890e..c977ce2 100644 --- a/html/lib/shader.js +++ b/html/lib/shader.js @@ -71,3 +71,37 @@ export class Shader { this.updateTime(); } } + +export const colorUtils = ` + vec3 rgb2hsv(vec3 c) { + vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0); + vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g)); + vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); + + float d = q.x - min(q.w, q.y); + float e = 1.0e-10; + return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); + } + + vec3 hsv2rgb(vec3 c) { + vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0); + vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); + return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); + } +`; + +export const commonFrag = ` + precision highp float; + + uniform float uTime; + uniform float uSinTime; + uniform float uCosTime; +`; + +export const commonVert = ` + attribute vec4 aVertexPosition; + attribute vec2 aTextureCoord; + + uniform mat4 uModelViewMatrix; + uniform mat4 uProjectionMatrix; +`; diff --git a/package.json b/package.json index c14195a..80d6bc1 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "noeidelon", "type": "module", - "main": "./generators/generate.ts", + "main": "./generators/generate.js", "scripts": { "build": "bun $BUNFLAGS ./generators/generate.ts", "build:watch": "BUNFLAGS=--watch bun run build",