diff --git a/README.md b/README.md index efedc55..332500f 100644 --- a/README.md +++ b/README.md @@ -133,6 +133,8 @@ Now you know link fu. Here's a list of customization options: - `palette` — with the normal "palette" effect, you can specify the colors and placement of the colors along the color grade as alternating *R,G,B,%* numeric values, like so: [https://rezmason.github.io/matrix/?palette=0.1,0,0.2,0,0.2,0.5,0,0.5,1,0.7,0,1](https://rezmason.github.io/matrix/?palette=0.1,0,0.2,0,0.2,0.5,0,0.5,1,0.7,0,1) - `backgroundColor`, `cursorColor`, `glintColor` — other *R,G,B* values that apply to the corresponding parts of the effect. - `paletteHSL`, `stripeHSL`, `backgroundHSL`, `cursorHSL`, and `glintHSL` — the same as the above, except they use *H,S,L* (hue, saturation, lightness) instead of *R,G,B*. +- `cursorIntensity`, — the brightness of cursors' glow. Can be any number greater than zero. Default is 2.0. +- `glintIntensity` — the brightness of glint glow, if there is any glint. Can be any number greater than zero. Default is 1.0. - `url` - if you set the effect to "image", this is how you specify which image to load. It doesn't work with any URL; I suggest grabbing them from Wikipedia: [https://rezmason.github.io/matrix/?effect=image&url=https://upload.wikimedia.org/wikipedia/commons/f/f5/EagleRock.jpg](https://rezmason.github.io/matrix/?effect=image&url=https://upload.wikimedia.org/wikipedia/commons/f/f5/EagleRock.jpg) - `loops` - (WIP) if set to "true", this causes the effect to loop, so that it can be converted into a looping video. - `fps` — the framerate of the effect. Can be any number between 0 and 60. Default is 60. diff --git a/js/config.js b/js/config.js index 4dbaaf3..3fd53f4 100644 --- a/js/config.js +++ b/js/config.js @@ -54,7 +54,7 @@ const fonts = { glyphMSDFURL: "assets/neomatrixology_msdf.png", glyphSequenceLength: 12, glyphTextureGridSize: [4, 4], - } + }, }; const textureURLs = { @@ -73,11 +73,13 @@ const defaults = { baseTexture: null, // The name of the texture to apply to the base layer of the glyphs glintTexture: null, // The name of the texture to apply to the glint layer of the glyphs useCamera: false, - backgroundColor: { space: "rgb", values: [0, 0, 0] }, // The color "behind" the glyphs + backgroundColor: hsl(0, 0, 0), // The color "behind" the glyphs isolateCursor: true, // Whether the "cursor"— the brightest glyph at the bottom of a raindrop— has its own color - cursorColor: { space: "rgb", values: [1.5, 2, 0.9] }, // The color of the cursor + cursorColor: hsl(0.242, 1, 0.73), // The color of the cursor + cursorIntensity: 2, // The intensity of the cursor isolateGlint: false, // Whether the "glint"— highlights on certain symbols in the font— should appear - glintColor: { space: "rgb", values: [1, 1, 1] }, // The color of the glint + glintColor: hsl(0, 0, 1), // The color of the glint + glintIntensity: 1, // The intensity of the glint volumetric: false, // A mode where the raindrops appear in perspective animationSpeed: 1, // The global rate that all animations progress fps: 60, // The target frame rate (frames per second) of the effect @@ -143,10 +145,12 @@ const versions = { { color: hsl(0.15, 0.9, 0.7), at: 0.7 }, { color: hsl(0.15, 0.9, 0.8), at: 0.8 }, ], - cursorColor: rgb(2, 2, 1) + cursorColor: hsl(0.167, 1, 0.75), + cursorIntensity: 2, }, operator: { - cursorColor: { space: "rgb", values: [1.0, 3, 1.5] }, + cursorColor: hsl(0.375, 1, 0.66), + cursorIntensity: 3, bloomSize: 0.6, bloomStrength: 0.75, highPassThreshold: 0.0, @@ -212,7 +216,8 @@ const versions = { resurrections: { font: "resurrections", glyphEdgeCrop: 0.1, - cursorColor: { space: "rgb", values: [1.4, 2, 1.2] }, + cursorColor: hsl(0.292, 1, 0.8), + cursorIntensity: 2, baseBrightness: -0.7, baseContrast: 1.17, highPassThreshold: 0, @@ -231,9 +236,11 @@ const versions = { glintTexture: "metal", baseTexture: "pixels", glyphEdgeCrop: 0.1, - cursorColor: { space: "rgb", values: [1.4, 2, 1.2] }, + cursorColor: hsl(0.292, 1, 0.8), + cursorIntensity: 2, isolateGlint: true, - glintColor: { space: "rgb", values: [3, 2.5, 0.6] }, + glintColor: hsl(0.131, 1, 0.6), + glintIntensity: 3, glintBrightness: -0.5, glintContrast: 1.5, baseBrightness: -0.4, @@ -258,9 +265,11 @@ const versions = { glintTexture: "mesh", baseTexture: "metal", glyphEdgeCrop: 0.1, - cursorColor: { space: "rgb", values: [1.4, 2, 1.4] }, + cursorColor: hsl(0.333, 1, 0.85), + cursorIntensity: 2, isolateGlint: true, - glintColor: { space: "rgb", values: [0, 2, 0.8] }, + glintColor: hsl(0.4, 1, 0.5), + glintIntensity: 2, glintBrightness: -1.5, glintContrast: 3, baseBrightness: -0.3, @@ -285,9 +294,11 @@ const versions = { glintTexture: "sand", baseTexture: "metal", glyphEdgeCrop: 0.1, - cursorColor: { space: "rgb", values: [0.6, 1, 2] }, + cursorColor: hsl(0.619, 1, 0.65), + cursorIntensity: 2, isolateGlint: true, - glintColor: { space: "rgb", values: [0.6, 1.2, 3] }, + glintColor: hsl(0.625, 1, 0.6), + glintIntensity: 3, glintBrightness: -1, glintContrast: 3, baseBrightness: -0.3, @@ -323,7 +334,8 @@ const versions = { }, twilight: { font: "huberfishD", - cursorColor: { space: "rgb", values: [1.5, 1, 0.9] }, + cursorColor: hsl(0.167, 1, 0.8), + cursorIntensity: 1.5, bloomStrength: 0.1, numColumns: 50, raindropLength: 0.9, @@ -342,9 +354,11 @@ const versions = { font: "resurrections", glintTexture: "metal", glyphEdgeCrop: 0.1, - cursorColor: { space: "rgb", values: [1.4, 2, 1.2] }, + cursorColor: hsl(0.292, 1, 0.8), + cursorIntensity: 2, isolateGlint: true, - glintColor: { space: "rgb", values: [3, 2.5, 0.6] }, + glintColor: hsl(0.131, 1, 0.6), + glintIntensity: 3, glintBrightness: -0.5, glintContrast: 1.5, baseBrightness: -0.4, @@ -474,6 +488,16 @@ const paramMapping = { cursorHSL: { key: "cursorColor", parser: parseColor(true) }, glintHSL: { key: "glintColor", parser: parseColor(true) }, + cursorIntensity: { + key: "cursorIntensity", + parser: (s) => nullNaN(range(parseFloat(s), 0, Infinity)), + }, + + glyphIntensity: { + key: "glyphIntensity", + parser: (s) => nullNaN(range(parseFloat(s), 0, Infinity)), + }, + volumetric: { key: "volumetric", parser: (s) => s.toLowerCase().includes("true") }, loops: { key: "loops", parser: (s) => s.toLowerCase().includes("true") }, fps: { key: "fps", parser: (s) => nullNaN(range(parseFloat(s), 0, 60)) }, @@ -503,11 +527,19 @@ export default (urlParams) => { if (validParams.effect != null) { if (validParams.cursorColor == null) { - validParams.cursorColor = { space: "rgb", values: [2, 2, 2] }; + validParams.cursorColor = hsl(0, 0, 1); + } + + if (validParams.cursorIntensity == null) { + validParams.cursorIntensity = 2; } if (validParams.glintColor == null) { - validParams.glintColor = { space: "rgb", values: [1, 1, 1] }; + validParams.glintColor = hsl(0, 0, 1); + } + + if (validParams.glyphIntensity == null) { + validParams.glyphIntensity = 1; } } diff --git a/js/regl/palettePass.js b/js/regl/palettePass.js index 4a3c31a..7c9a548 100644 --- a/js/regl/palettePass.js +++ b/js/regl/palettePass.js @@ -57,7 +57,7 @@ const makePalette = (regl, entries) => { export default ({ regl, config }, inputs) => { const output = makePassFBO(regl, config.useHalfFloat); const paletteTex = makePalette(regl, config.palette); - const { backgroundColor, cursorColor, glintColor, ditherMagnitude } = config; + const { backgroundColor, cursorColor, glintColor, cursorIntensity, glintIntensity, ditherMagnitude } = config; const palettePassFrag = loadText("shaders/glsl/palettePass.frag.glsl"); @@ -68,6 +68,8 @@ export default ({ regl, config }, inputs) => { backgroundColor: colorToRGB(backgroundColor), cursorColor: colorToRGB(cursorColor), glintColor: colorToRGB(glintColor), + cursorIntensity, + glintIntensity, ditherMagnitude, tex: inputs.primary, bloomTex: inputs.bloom, diff --git a/js/regl/stripePass.js b/js/regl/stripePass.js index 1c75911..a45dd61 100644 --- a/js/regl/stripePass.js +++ b/js/regl/stripePass.js @@ -30,7 +30,7 @@ const prideStripeColors = [ export default ({ regl, config }, inputs) => { const output = makePassFBO(regl, config.useHalfFloat); - const { backgroundColor, cursorColor, glintColor, ditherMagnitude } = config; + const { backgroundColor, cursorColor, glintColor, cursorIntensity, glintIntensity, ditherMagnitude } = config; // Expand and convert stripe colors into 1D texture data const stripeColors = "stripeColors" in config ? config.stripeColors : config.effect === "pride" ? prideStripeColors : transPrideStripeColors; @@ -48,6 +48,8 @@ export default ({ regl, config }, inputs) => { backgroundColor: colorToRGB(backgroundColor), cursorColor: colorToRGB(cursorColor), glintColor: colorToRGB(glintColor), + cursorIntensity, + glintIntensity, ditherMagnitude, tex: inputs.primary, bloomTex: inputs.bloom, diff --git a/js/webgpu/palettePass.js b/js/webgpu/palettePass.js index 2550db0..7e2b479 100644 --- a/js/webgpu/palettePass.js +++ b/js/webgpu/palettePass.js @@ -100,6 +100,8 @@ export default ({ config, device, timeBuffer }) => { backgroundColor: colorToRGB(config.backgroundColor), cursorColor: colorToRGB(config.cursorColor), glintColor: colorToRGB(config.glintColor), + cursorIntensity: config.cursorIntensity, + glintIntensity: config.glintIntensity, }); const paletteUniforms = paletteShaderUniforms.Palette; diff --git a/js/webgpu/stripePass.js b/js/webgpu/stripePass.js index 972b223..3f709ce 100644 --- a/js/webgpu/stripePass.js +++ b/js/webgpu/stripePass.js @@ -75,6 +75,8 @@ export default ({ config, device, timeBuffer }) => { backgroundColor: colorToRGB(config.backgroundColor), cursorColor: colorToRGB(config.cursorColor), glintColor: colorToRGB(config.glintColor), + cursorIntensity: config.cursorIntensity, + glintIntensity: config.glintIntensity, }); })(); diff --git a/shaders/glsl/palettePass.frag.glsl b/shaders/glsl/palettePass.frag.glsl index 148bdef..6fda862 100644 --- a/shaders/glsl/palettePass.frag.glsl +++ b/shaders/glsl/palettePass.frag.glsl @@ -7,6 +7,7 @@ uniform sampler2D paletteTex; uniform float ditherMagnitude; uniform float time; uniform vec3 backgroundColor, cursorColor, glintColor; +uniform float cursorIntensity, glintIntensity; varying vec2 vUV; highp float rand( const in vec2 uv, const in float t ) { @@ -30,8 +31,8 @@ void main() { // Map the brightness to a position in the palette texture gl_FragColor = vec4( texture2D( paletteTex, vec2(brightness.r, 0.0)).rgb - + min(cursorColor * brightness.g, vec3(1.0)) - + min(glintColor * brightness.b, vec3(1.0)) + + min(cursorColor * cursorIntensity * brightness.g, vec3(1.0)) + + min(glintColor * glintIntensity * brightness.b, vec3(1.0)) + backgroundColor, 1.0 ); diff --git a/shaders/glsl/stripePass.frag.glsl b/shaders/glsl/stripePass.frag.glsl index da96760..dbd5280 100644 --- a/shaders/glsl/stripePass.frag.glsl +++ b/shaders/glsl/stripePass.frag.glsl @@ -7,6 +7,7 @@ uniform sampler2D stripeTex; uniform float ditherMagnitude; uniform float time; uniform vec3 backgroundColor, cursorColor, glintColor; +uniform float cursorIntensity, glintIntensity; varying vec2 vUV; highp float rand( const in vec2 uv, const in float t ) { @@ -31,8 +32,8 @@ void main() { gl_FragColor = vec4( color * brightness.r - + min(cursorColor * brightness.g, vec3(1.0)) - + min(glintColor * brightness.b, vec3(1.0)) + + min(cursorColor * cursorIntensity * brightness.g, vec3(1.0)) + + min(glintColor * glintIntensity * brightness.b, vec3(1.0)) + backgroundColor, 1.0 ); diff --git a/shaders/wgsl/palettePass.wgsl b/shaders/wgsl/palettePass.wgsl index 2ad8455..bbe8e4d 100644 --- a/shaders/wgsl/palettePass.wgsl +++ b/shaders/wgsl/palettePass.wgsl @@ -3,6 +3,8 @@ struct Config { backgroundColor : vec3, cursorColor : vec3, glintColor : vec3, + cursorIntensity : f32, + glintIntensity : f32, }; struct Palette { @@ -65,8 +67,8 @@ fn getBrightness(uv : vec2) -> vec4 { textureStore(outputTex, coord, vec4( palette.colors[paletteIndex] - + min(config.cursorColor * brightness.g, vec3(1.0)) - + min(config.glintColor * brightness.b, vec3(1.0)) + + min(config.cursorColor * config.cursorIntensity * brightness.g, vec3(1.0)) + + min(config.glintColor * config.glintIntensity * brightness.b, vec3(1.0)) + config.backgroundColor, 1.0 )); diff --git a/shaders/wgsl/stripePass.wgsl b/shaders/wgsl/stripePass.wgsl index 6ef82d2..0a6b3e4 100644 --- a/shaders/wgsl/stripePass.wgsl +++ b/shaders/wgsl/stripePass.wgsl @@ -3,6 +3,8 @@ struct Config { backgroundColor : vec3, cursorColor : vec3, glintColor : vec3, + cursorIntensity : f32, + glintIntensity : f32, }; struct Time { @@ -60,8 +62,8 @@ fn getBrightness(uv : vec2) -> vec4 { textureStore(outputTex, coord, vec4( color * brightness.r - + min(config.cursorColor * brightness.g, vec3(1.0)) - + min(config.glintColor * brightness.b, vec3(1.0)) + + min(config.cursorColor * config.cursorIntensity * brightness.g, vec3(1.0)) + + min(config.glintColor * config.glintIntensity * brightness.b, vec3(1.0)) + config.backgroundColor, 1.0 ));