diff --git a/js/config.js b/js/config.js index afd814f..4ff73b1 100644 --- a/js/config.js +++ b/js/config.js @@ -369,18 +369,12 @@ versions["2021"] = versions.resurrections; const range = (f, min = -Infinity, max = Infinity) => Math.max(min, Math.min(max, f)); const nullNaN = (f) => (isNaN(f) ? null : f); -const clumpArray = (array, clumpSize) => - array.reduce((result, value) => { - if (result.length > 0) { - const last = result[result.length - 1]; - if (last.length < clumpSize) { - last.push(value); - return result; - } - } - result.push([value]); - return result; - }, []); +const parseColors = (isHSL) => (s) => { + const values = s.split(",").map(parseFloat); + return Array(Math.floor(values.length / 3)) + .fill() + .map((_, index) => values.slice(index * 3, (index + 1) * 3)); +}; const paramMapping = { version: { key: "version", parser: (s) => s }, @@ -422,10 +416,10 @@ const paramMapping = { parser: (s) => nullNaN(range(parseFloat(s), 0, 1)), }, url: { key: "bgURL", parser: (s) => s }, - stripeColors: { key: "stripeColors", parser: (s) => s }, - backgroundColor: { key: "backgroundColor", parser: (s) => s.split(",").map(parseFloat) }, - cursorColor: { key: "cursorColor", parser: (s) => s.split(",").map(parseFloat) }, - glintColor: { key: "glintColor", parser: (s) => s.split(",").map(parseFloat) }, + stripeColors: { key: "stripeColors", parser: parseColors(false) }, + backgroundColor: { key: "backgroundColor", parser: parseColors(false) }, + cursorColor: { key: "cursorColor", parser: parseColors(false) }, + glintColor: { key: "glintColor", parser: parseColors(false) }, volumetric: { key: "volumetric", parser: (s) => s.toLowerCase().includes("true") }, loops: { key: "loops", parser: (s) => s.toLowerCase().includes("true") }, skipIntro: { key: "skipIntro", parser: (s) => s.toLowerCase().includes("true") }, diff --git a/js/regl/stripePass.js b/js/regl/stripePass.js index 4af4377..6c43ddb 100644 --- a/js/regl/stripePass.js +++ b/js/regl/stripePass.js @@ -7,36 +7,24 @@ import { loadText, make1DTexture, makePassFBO, makePass } from "./utils.js"; const transPrideStripeColors = [ [0.36, 0.81, 0.98], - [0.36, 0.81, 0.98], - [0.36, 0.81, 0.98], - [0.96, 0.66, 0.72], - [0.96, 0.66, 0.72], [0.96, 0.66, 0.72], [1.0, 1.0, 1.0], - [1.0, 1.0, 1.0], - [1.0, 1.0, 1.0], - [0.96, 0.66, 0.72], - [0.96, 0.66, 0.72], [0.96, 0.66, 0.72], [0.36, 0.81, 0.98], - [0.36, 0.81, 0.98], - [0.36, 0.81, 0.98], -].flat(); +] + .map((color) => Array(3).fill(color)) + .flat(); const prideStripeColors = [ [0.89, 0.01, 0.01], - [0.89, 0.01, 0.01], - [1.0, 0.55, 0.0], [1.0, 0.55, 0.0], [1.0, 0.93, 0.0], - [1.0, 0.93, 0.0], - [0.0, 0.5, 0.15], [0.0, 0.5, 0.15], [0.0, 0.3, 1.0], - [0.0, 0.3, 1.0], [0.46, 0.03, 0.53], - [0.46, 0.03, 0.53], -].flat(); +] + .map((color) => Array(2).fill(color)) + .flat(); export default ({ regl, config }, inputs) => { const output = makePassFBO(regl, config.useHalfFloat); @@ -44,12 +32,10 @@ export default ({ regl, config }, inputs) => { const { backgroundColor, cursorColor, glintColor, ditherMagnitude, bloomStrength } = config; // Expand and convert stripe colors into 1D texture data - const stripeColors = - "stripeColors" in config ? config.stripeColors.split(",").map(parseFloat) : config.effect === "pride" ? prideStripeColors : transPrideStripeColors; - const numStripeColors = Math.floor(stripeColors.length / 3); - const stripes = make1DTexture( + const stripeColors = "stripeColors" in config ? config.stripeColors : config.effect === "pride" ? prideStripeColors : transPrideStripeColors; + const stripeTex = make1DTexture( regl, - stripeColors.slice(0, numStripeColors * 3).map((f) => Math.floor(f * 0xff)) + stripeColors.map((rgb) => [...rgb, 1]) ); const stripePassFrag = loadText("shaders/glsl/stripePass.frag.glsl"); @@ -65,7 +51,7 @@ export default ({ regl, config }, inputs) => { bloomStrength, tex: inputs.primary, bloomTex: inputs.bloom, - stripes, + stripeTex, }, framebuffer: output, }); diff --git a/js/regl/utils.js b/js/regl/utils.js index 1c33ec9..36085f2 100644 --- a/js/regl/utils.js +++ b/js/regl/utils.js @@ -110,15 +110,17 @@ const makeFullScreenQuad = (regl, uniforms = {}, context = {}) => depth: { enable: false }, }); -const make1DTexture = (regl, data) => - regl.texture({ +const make1DTexture = (regl, rgbas) => { + const data = rgbas.map((rgba) => rgba.map((f) => Math.floor(f * 0xff))).flat(); + return regl.texture({ data, - width: data.length / 3, + width: data.length / 4, height: 1, - format: "rgb", + format: "rgba", mag: "linear", min: "linear", }); +}; const makePass = (outputs, ready, setSize, execute) => ({ outputs: outputs ?? {}, diff --git a/js/webgpu/stripePass.js b/js/webgpu/stripePass.js index 667422a..831b761 100644 --- a/js/webgpu/stripePass.js +++ b/js/webgpu/stripePass.js @@ -7,27 +7,25 @@ import { loadShader, make1DTexture, makeUniformBuffer, makeBindGroup, makeComput // This shader introduces noise into the renders, to avoid banding 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], + [0.36, 0.81, 0.98], + [0.96, 0.66, 0.72], [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(); + [0.96, 0.66, 0.72], + [0.36, 0.81, 0.98], +] + .map((color) => Array(3).fill(color)) + .flat(1); const prideStripeColors = [ - [1, 0, 0], - [1, 0.5, 0], - [1, 1, 0], - [0, 1, 0], - [0, 0, 1], - [0.8, 0, 1], -].flat(); + [0.89, 0.01, 0.01], + [1.0, 0.55, 0.0], + [1.0, 0.93, 0.0], + [0.0, 0.5, 0.15], + [0.0, 0.3, 1.0], + [0.46, 0.03, 0.53], +] + .map((color) => Array(2).fill(color)) + .flat(1); const numVerticesPerQuad = 2 * 3; @@ -39,14 +37,11 @@ const numVerticesPerQuad = 2 * 3; export default ({ config, device, timeBuffer }) => { // Expand and convert stripe colors into 1D texture data - const input = - "stripeColors" in config ? config.stripeColors.split(",").map(parseFloat) : config.effect === "pride" ? prideStripeColors : transPrideStripeColors; - - const stripeColors = Array(Math.floor(input.length / 3)) - .fill() - .map((_, index) => [...input.slice(index * 3, (index + 1) * 3), 1]); - - const stripeTexture = make1DTexture(device, stripeColors); + const stripeColors = "stripeColors" in config ? config.stripeColors : config.effect === "pride" ? prideStripeColors : transPrideStripeColors; + const stripeTex = make1DTexture( + device, + stripeColors.map((rgb) => [...rgb, 1]) + ); const linearSampler = device.createSampler({ magFilter: "linear", @@ -105,7 +100,7 @@ export default ({ config, device, timeBuffer }) => { linearSampler, tex.createView(), bloomTex.createView(), - stripeTexture.createView(), + stripeTex.createView(), output.createView(), ]); computePass.setBindGroup(0, computeBindGroup); diff --git a/shaders/glsl/stripePass.frag.glsl b/shaders/glsl/stripePass.frag.glsl index 425a0a4..2143404 100644 --- a/shaders/glsl/stripePass.frag.glsl +++ b/shaders/glsl/stripePass.frag.glsl @@ -4,7 +4,7 @@ precision mediump float; uniform sampler2D tex; uniform sampler2D bloomTex; uniform float bloomStrength; -uniform sampler2D stripes; +uniform sampler2D stripeTex; uniform float ditherMagnitude; uniform float time; uniform vec3 backgroundColor, cursorColor, glintColor; @@ -23,7 +23,7 @@ vec4 getBrightness(vec2 uv) { } void main() { - vec3 color = texture2D(stripes, vUV).rgb; + vec3 color = texture2D(stripeTex, vUV).rgb; vec4 brightness = getBrightness(vUV); diff --git a/shaders/wgsl/stripePass.wgsl b/shaders/wgsl/stripePass.wgsl index 3b4b18a..38c6726 100644 --- a/shaders/wgsl/stripePass.wgsl +++ b/shaders/wgsl/stripePass.wgsl @@ -16,7 +16,7 @@ struct Time { @group(0) @binding(2) var linearSampler : sampler; @group(0) @binding(3) var tex : texture_2d; @group(0) @binding(4) var bloomTex : texture_2d; -@group(0) @binding(5) var stripeTexture : texture_2d; +@group(0) @binding(5) var stripeTex : texture_2d; @group(0) @binding(6) var outputTex : texture_storage_2d; struct ComputeInput { @@ -52,7 +52,7 @@ fn getBrightness(uv : vec2) -> vec4 { var uv = vec2(coord) / vec2(screenSize); - var color = textureSampleLevel( stripeTexture, linearSampler, uv, 0.0 ).rgb; + var color = textureSampleLevel( stripeTex, linearSampler, uv, 0.0 ).rgb; var brightness = getBrightness(uv);