diff --git a/js/bloomPass.js b/js/bloomPass.js index 323df2a..d439706 100644 --- a/js/bloomPass.js +++ b/js/bloomPass.js @@ -1,4 +1,4 @@ -import { loadText, extractEntries, makePassFBO, makePyramid, resizePyramid, makePass } from "./utils.js"; +import { loadText, makePassFBO, makePyramid, resizePyramid, makePass } from "./utils.js"; // The bloom pass is basically an added high-pass blur. @@ -18,7 +18,7 @@ export default (regl, config, inputs) => { }); } - const uniforms = extractEntries(config, ["bloomStrength", "highPassThreshold"]); + const { bloomStrength, highPassThreshold } = config; const highPassPyramid = makePyramid(regl, pyramidHeight, config.useHalfFloat); const hBlurPyramid = makePyramid(regl, pyramidHeight, config.useHalfFloat); @@ -31,7 +31,7 @@ export default (regl, config, inputs) => { const highPass = regl({ frag: regl.prop("frag"), uniforms: { - ...uniforms, + highPassThreshold, tex: regl.prop("tex"), }, framebuffer: regl.prop("fbo"), @@ -45,7 +45,6 @@ export default (regl, config, inputs) => { const blur = regl({ frag: regl.prop("frag"), uniforms: { - ...uniforms, tex: regl.prop("tex"), direction: regl.prop("direction"), height: regl.context("viewportWidth"), @@ -68,7 +67,7 @@ export default (regl, config, inputs) => { } `, uniforms: { - ...uniforms, + bloomStrength, ...Object.fromEntries(vBlurPyramid.map((fbo, index) => [`pyr_${index}`, fbo])), }, framebuffer: output, diff --git a/js/main.js b/js/main.js index 7915138..ce5bb25 100644 --- a/js/main.js +++ b/js/main.js @@ -26,6 +26,8 @@ const effects = { customStripes: makeStripePass, stripes: makeStripePass, pride: makeStripePass, + transPride: makeStripePass, + trans: makeStripePass, image: makeImagePass, resurrection: makeResurrectionPass, resurrections: makeResurrectionPass, diff --git a/js/palettePass.js b/js/palettePass.js index d708997..a5aa4b4 100644 --- a/js/palettePass.js +++ b/js/palettePass.js @@ -1,4 +1,4 @@ -import { loadText, extractEntries, make1DTexture, makePassFBO, makePass } from "./utils.js"; +import { loadText, make1DTexture, makePassFBO, makePass } from "./utils.js"; const colorToRGB = ([hue, saturation, lightness]) => { const a = saturation * Math.min(lightness, 1 - lightness); @@ -55,6 +55,7 @@ const makePalette = (regl, entries) => { export default (regl, config, inputs) => { const output = makePassFBO(regl, config.useHalfFloat); const palette = makePalette(regl, config.paletteEntries); + const { backgroundColor } = config; const palettePassFrag = loadText("../shaders/palettePass.frag"); @@ -62,7 +63,7 @@ export default (regl, config, inputs) => { frag: regl.prop("frag"), uniforms: { - ...extractEntries(config, ["backgroundColor"]), + backgroundColor, tex: inputs.primary, bloomTex: inputs.bloom, palette, diff --git a/js/renderer.js b/js/renderer.js index 002cccd..1ffbe82 100644 --- a/js/renderer.js +++ b/js/renderer.js @@ -1,4 +1,6 @@ -import { extractEntries, loadImage, loadText, makePassFBO, makeDoubleBuffer, makePass } from "./utils.js"; +import { loadImage, loadText, makePassFBO, makeDoubleBuffer, makePass } from "./utils.js"; + +const extractEntries = (src, keys) => Object.fromEntries(Array.from(Object.entries(src)).filter(([key]) => keys.includes(key))); const rippleTypes = { box: 0, @@ -19,22 +21,11 @@ export default (regl, config) => { const [numQuadRows, numQuadColumns] = volumetric ? [numRows, numColumns] : [1, 1]; const numQuads = numQuadRows * numQuadColumns; const quadSize = [1 / numQuadColumns, 1 / numQuadRows]; - - // These two framebuffers are used to compute the raining code. - // they take turns being the source and destination of the "compute" shader. - // The half float data type is crucial! It lets us store almost any real number, - // whereas the default type limits us to integers between 0 and 255. - - // This double buffer is smaller than the screen, because its pixels correspond - // with glyphs in the final image, and the glyphs are much larger than a pixel. - const doubleBuffer = makeDoubleBuffer(regl, { - width: numColumns, - height: numRows, - wrapT: "clamp", - type: "half float", - }); - - const output = makePassFBO(regl, config.useHalfFloat); + const rippleType = config.rippleTypeName in rippleTypes ? rippleTypes[config.rippleTypeName] : -1; + const cycleStyle = config.cycleStyleName in cycleStyles ? cycleStyles[config.cycleStyleName] : 0; + const slantVec = [Math.cos(config.slant), Math.sin(config.slant)]; + const slantScale = 1 / (Math.abs(Math.sin(2 * config.slant)) * (Math.sqrt(2) - 1) + 1); + const showComputationTexture = config.effect === "none"; const uniforms = { ...extractEntries(config, [ @@ -71,16 +62,31 @@ export default (regl, config) => { numQuadColumns, quadSize, volumetric, + rippleType, + cycleStyle, + slantVec, + slantScale, + showComputationTexture, }; - uniforms.rippleType = config.rippleTypeName in rippleTypes ? rippleTypes[config.rippleTypeName] : -1; - uniforms.cycleStyle = config.cycleStyleName in cycleStyles ? cycleStyles[config.cycleStyleName] : 0; - uniforms.slantVec = [Math.cos(config.slant), Math.sin(config.slant)]; - uniforms.slantScale = 1 / (Math.abs(Math.sin(2 * config.slant)) * (Math.sqrt(2) - 1) + 1); - uniforms.showComputationTexture = config.effect === "none"; - const msdf = loadImage(regl, config.glyphTexURL); + // These two framebuffers are used to compute the raining code. + // they take turns being the source and destination of the "compute" shader. + // The half float data type is crucial! It lets us store almost any real number, + // whereas the default type limits us to integers between 0 and 255. + + // This double buffer is smaller than the screen, because its pixels correspond + // with glyphs in the final image, and the glyphs are much larger than a pixel. + const doubleBuffer = makeDoubleBuffer(regl, { + width: numColumns, + height: numRows, + wrapT: "clamp", + type: "half float", + }); + + const output = makePassFBO(regl, config.useHalfFloat); + const updateFrag = loadText("../shaders/update.frag"); const update = regl({ frag: regl.prop("frag"), diff --git a/js/resurrectionPass.js b/js/resurrectionPass.js index b8ec04f..0a9f52c 100644 --- a/js/resurrectionPass.js +++ b/js/resurrectionPass.js @@ -1,24 +1,15 @@ -import { loadText, extractEntries, make1DTexture, makePassFBO, makePass } from "./utils.js"; - -const colorToRGB = ([hue, saturation, lightness]) => { - const a = saturation * Math.min(lightness, 1 - lightness); - const f = (n) => { - const k = (n + hue * 12) % 12; - return lightness - a * Math.max(-1, Math.min(k - 3, 9 - k, 1)); - }; - return [f(0), f(8), f(4)]; -}; +import { loadText, make1DTexture, makePassFBO, makePass } from "./utils.js"; export default (regl, config, inputs) => { const output = makePassFBO(regl, config.useHalfFloat); - + const { backgroundColor } = config; const resurrectionPassFrag = loadText("../shaders/resurrectionPass.frag"); const render = regl({ frag: regl.prop("frag"), uniforms: { - ...extractEntries(config, ["backgroundColor"]), + backgroundColor, tex: inputs.primary, bloomTex: inputs.bloom, ditherMagnitude: 0.05, diff --git a/js/stripePass.js b/js/stripePass.js index 0ec73ea..229bebc 100644 --- a/js/stripePass.js +++ b/js/stripePass.js @@ -1,12 +1,17 @@ -import { loadText, extractEntries, make1DTexture, makePassFBO, makePass } from "./utils.js"; +import { loadText, make1DTexture, makePassFBO, makePass } from "./utils.js"; -const neapolitanStripeColors = [ - [0.4, 0.15, 0.1], - [0.4, 0.15, 0.1], - [0.8, 0.8, 0.6], - [0.8, 0.8, 0.6], - [1.0, 0.7, 0.8], - [1.0, 0.7, 0.8], +const transPrideStripeColors = [ + [0.3, 1.0, 1.0], + [0.3, 1.0, 1.0], + [1.0, 0.5, 0.8], + [1.0, 0.5, 0.8], + [1.0, 1.0, 1.0], + [1.0, 1.0, 1.0], + [1.0, 1.0, 1.0], + [1.0, 0.5, 0.8], + [1.0, 0.5, 0.8], + [0.3, 1.0, 1.0], + [0.3, 1.0, 1.0], ].flat(); const prideStripeColors = [ @@ -21,8 +26,9 @@ const prideStripeColors = [ export default (regl, config, inputs) => { const output = makePassFBO(regl, config.useHalfFloat); + const { backgroundColor } = config; const stripeColors = - "stripeColors" in config ? config.stripeColors.split(",").map(parseFloat) : config.effect === "pride" ? prideStripeColors : neapolitanStripeColors; + "stripeColors" in config ? config.stripeColors.split(",").map(parseFloat) : config.effect === "pride" ? prideStripeColors : transPrideStripeColors; const numStripeColors = Math.floor(stripeColors.length / 3); const stripes = make1DTexture( regl, @@ -35,7 +41,7 @@ export default (regl, config, inputs) => { frag: regl.prop("frag"), uniforms: { - ...extractEntries(config, ["backgroundColor"]), + backgroundColor, tex: inputs.primary, bloomTex: inputs.bloom, stripes, diff --git a/js/utils.js b/js/utils.js index 1d08d1f..1114da3 100644 --- a/js/utils.js +++ b/js/utils.js @@ -1,5 +1,3 @@ -const extractEntries = (src, keys) => Object.fromEntries(Array.from(Object.entries(src)).filter(([key]) => keys.includes(key))); - const makePassTexture = (regl, halfFloat) => regl.texture({ width: 1, @@ -182,7 +180,6 @@ const makePipeline = (steps, getInputs, ...params) => steps.filter((f) => f != null).reduce((pipeline, f, i) => [...pipeline, f(...params, i == 0 ? null : getInputs(pipeline[i - 1]))], []); export { - extractEntries, makePassTexture, makePassFBO, makeDoubleBuffer,