From eddbd12c36704690ce2d7cc5eea5cc47fefe3648 Mon Sep 17 00:00:00 2001 From: Rezmason Date: Sat, 17 Sep 2022 10:09:52 -0700 Subject: [PATCH] Added glint brightness and contrast, makes a big difference --- TODO.txt | 14 +++---- js/config.js | 4 +- js/regl/rainPass.js | 2 + shaders/glsl/rainPass.frag.glsl | 41 ++++++++++++++------- shaders/glsl/rainPass.raindrop.frag.glsl | 4 +- shaders/wgsl/rainPass.wgsl | 47 +++++++++++++----------- 6 files changed, 66 insertions(+), 46 deletions(-) diff --git a/TODO.txt b/TODO.txt index 6c068ce..d385b7e 100644 --- a/TODO.txt +++ b/TODO.txt @@ -1,5 +1,11 @@ TODO: +Multiply glints and bases by texture + Base: grid + Trinity glint: worn metal + Morpheus glint: hex mesh + Bugs glint: horizontal grooves + Audio system Toggle (or number representing frequency) Load the sound effect @@ -16,14 +22,6 @@ Playdate version Docking sound Maybe crank sounds? Not sure yet -Support Resurrections anomaly streaks - grit texture multiply - Lighting - Different parts of a streak glow at different intensities, at different times - The streaks often dim slower, ie. are brighter, than the glyphs beneath them - Different brightness/contrast? - Imagine they're metallic or something - Support Resurrections SDF bevel and "lights" https://shaderfun.com/2018/07/23/signed-distance-fields-part-8-gradients-bevels-and-noise/ Get the "normals" and color right diff --git a/js/config.js b/js/config.js index f009965..045ea10 100644 --- a/js/config.js +++ b/js/config.js @@ -70,6 +70,8 @@ const defaults = { cycleFrameSkip: 1, // The global minimum number of frames between glyphs cycling baseBrightness: -0.5, // The brightness of the glyphs, before any effects are applied baseContrast: 1.1, // The contrast of the glyphs, before any effects are applied + glintBrightness: -2, // The brightness of the glints, before any effects are applied + glintContrast: 3, // The contrast of the glints, before any effects are applied brightnessOverride: 0.0, // A global override to the brightness of displayed glyphs. Only used if it is > 0. brightnessThreshold: 0, // The minimum brightness for a glyph to still be considered visible brightnessDecay: 1.0, // The rate at which glyphs light up and dim @@ -196,7 +198,7 @@ const versions = { glyphEdgeCrop: 0.1, cursorColor: [1.4, 2, 1.2], isolateGlint: true, - glintColor: [2, 1.5, 0.5], + glintColor: [1.6, 1.5, 0.5], baseBrightness: -0.9, baseContrast: 1.5, highPassThreshold: 0, diff --git a/js/regl/rainPass.js b/js/regl/rainPass.js index 464ed2f..bbdafb5 100644 --- a/js/regl/rainPass.js +++ b/js/regl/rainPass.js @@ -129,6 +129,8 @@ export default ({ regl, config, lkg }) => { // fragment "baseBrightness", "baseContrast", + "glintBrightness", + "glintContrast", "brightnessThreshold", "brightnessOverride", "isolateCursor", diff --git a/shaders/glsl/rainPass.frag.glsl b/shaders/glsl/rainPass.frag.glsl index 2ec4937..bef4014 100644 --- a/shaders/glsl/rainPass.frag.glsl +++ b/shaders/glsl/rainPass.frag.glsl @@ -8,7 +8,7 @@ uniform sampler2D raindropState, symbolState, effectState; uniform float numColumns, numRows; uniform sampler2D glyphTex, glintTex; uniform float glyphHeightToWidth, glyphSequenceLength, glyphEdgeCrop; -uniform float baseContrast, baseBrightness; +uniform float baseContrast, baseBrightness, glintContrast, glintBrightness; uniform float brightnessOverride, brightnessThreshold; uniform vec2 glyphTextureGridSize; uniform vec2 slantVec; @@ -58,26 +58,35 @@ vec2 getUV(vec2 uv) { return uv; } -vec2 getBrightness(float brightness, float cursor, float multipliedEffects, float addedEffects) { - if (!isolateCursor) { - cursor = 0.; - } - brightness = (1. - brightness) * baseContrast + baseBrightness; +vec3 getBrightness(vec4 raindrop, vec4 effect, float quadDepth) { + + float base = raindrop.r; + bool isCursor = bool(raindrop.g) && isolateCursor; + float glint = base; + float multipliedEffects = effect.r; + float addedEffects = effect.g; + + base = base * baseContrast + baseBrightness; + glint = glint * glintContrast + glintBrightness; // Modes that don't fade glyphs set their actual brightness here - if (brightnessOverride > 0. && brightness > brightnessThreshold && cursor == 0.) { - brightness = brightnessOverride; + if (brightnessOverride > 0. && base > brightnessThreshold && !isCursor) { + base = brightnessOverride; } - brightness *= multipliedEffects; - brightness += addedEffects; + base = base * multipliedEffects + addedEffects; + glint = glint * multipliedEffects + addedEffects; // In volumetric mode, distant glyphs are dimmer if (volumetric && !showDebugView) { - brightness = brightness * min(1., vDepth); + base = base * min(1.0, quadDepth); + glint = glint * min(1.0, quadDepth); } - return vec2(brightness * (1. - cursor), brightness * cursor); + return vec3( + (isCursor ? vec2(0.0, 1.0) : vec2(1.0, 0.0)) * base, + glint + ); } vec2 getSymbolUV(float index) { @@ -121,7 +130,11 @@ void main() { vec4 symbolData = volumetric ? vSymbol : texture2D( symbolState, uv); vec4 effectData = volumetric ? vEffect : texture2D( effectState, uv); - vec2 brightness = getBrightness(raindropData.r, raindropData.g, effectData.r, effectData.g); + vec3 brightness = getBrightness( + raindropData, + effectData, + vDepth + ); vec2 symbol = getSymbol(uv, symbolData.r); if (showDebugView) { @@ -136,6 +149,6 @@ void main() { 1. ); } else { - gl_FragColor = vec4(brightness * symbol.r, brightness.r * symbol.g, 0.); + gl_FragColor = vec4(brightness.rg * symbol.r, brightness.b * symbol.g, 0.); } } diff --git a/shaders/glsl/rainPass.raindrop.frag.glsl b/shaders/glsl/rainPass.raindrop.frag.glsl index db2db56..5407dd3 100644 --- a/shaders/glsl/rainPass.raindrop.frag.glsl +++ b/shaders/glsl/rainPass.raindrop.frag.glsl @@ -56,7 +56,7 @@ float getRainBrightness(float simTime, vec2 glyphPos) { if (!loops) { rainTime = wobble(rainTime); } - return fract(rainTime); + return 1.0 - fract(rainTime); } // Main function @@ -64,7 +64,7 @@ float getRainBrightness(float simTime, vec2 glyphPos) { vec4 computeResult(float simTime, bool isFirstFrame, vec2 glyphPos, vec2 screenPos, vec4 previous) { float brightness = getRainBrightness(simTime, glyphPos); float brightnessBelow = getRainBrightness(simTime, glyphPos + vec2(0., -1.)); - float cursor = brightness < brightnessBelow ? 1.0 : 0.0; + float cursor = brightness > brightnessBelow ? 1.0 : 0.0; // Blend the glyph's brightness with its previous brightness, so it winks on and off organically if (!isFirstFrame) { diff --git a/shaders/wgsl/rainPass.wgsl b/shaders/wgsl/rainPass.wgsl index 5309a3b..14f7ba4 100644 --- a/shaders/wgsl/rainPass.wgsl +++ b/shaders/wgsl/rainPass.wgsl @@ -29,6 +29,8 @@ struct Config { forwardSpeed : f32, baseBrightness : f32, baseContrast : f32, + glintBrightness : f32, + glintContrast : f32, glyphVerticalSpacing : f32, glyphEdgeCrop : f32, isPolar : i32, @@ -144,7 +146,7 @@ fn getRainBrightness(simTime : f32, glyphPos : vec2) -> f32 { if (!bool(config.loops)) { rainTime = wobble(rainTime); } - return fract(rainTime); + return 1.0 - fract(rainTime); } // Compute shader additional effects @@ -203,7 +205,7 @@ fn computeRaindrop (simTime : f32, isFirstFrame : bool, glyphPos : vec2, sc var brightness = getRainBrightness(simTime, glyphPos); var brightnessBelow = getRainBrightness(simTime, glyphPos + vec2(0., -1.)); - var cursor = select(0.0, 1.0, brightness < brightnessBelow); + var cursor = select(0.0, 1.0, brightness > brightnessBelow); // Blend the glyph's brightness with its previous brightness, so it winks on and off organically if (!isFirstFrame) { @@ -371,30 +373,35 @@ fn getUV(inputUV : vec2) -> vec2 { return uv; } -fn getBrightness(inputBrightness : f32, cursor : f32, quadDepth : f32, multipliedEffects : f32, addedEffects : f32) -> vec2 { +fn getBrightness(raindrop : vec4, effect : vec4, quadDepth : f32) -> vec3 { - var isCursor = bool(cursor); + var base = raindrop.r; + var isCursor = bool(raindrop.g) && bool(config.isolateCursor); + var glint = base; + var multipliedEffects = effect.r; + var addedEffects = effect.g; - if (!bool(config.isolateCursor)) { - isCursor = false; - } - - var brightness = (1.0 - inputBrightness) * config.baseContrast + config.baseBrightness; + base = base * config.baseContrast + config.baseBrightness; + glint = glint * config.glintContrast + config.glintBrightness; // Modes that don't fade glyphs set their actual brightness here - if (config.brightnessOverride > 0. && brightness > config.brightnessThreshold && !isCursor) { - brightness = config.brightnessOverride; + if (config.brightnessOverride > 0. && base > config.brightnessThreshold && !isCursor) { + base = config.brightnessOverride; } - brightness *= multipliedEffects; - brightness += addedEffects; + base = base * multipliedEffects + addedEffects; + glint = glint * multipliedEffects + addedEffects; // In volumetric mode, distant glyphs are dimmer if (bool(config.volumetric) && !bool(config.showDebugView)) { - brightness = brightness * min(1.0, quadDepth); + base = base * min(1.0, quadDepth); + glint = glint * min(1.0, quadDepth); } - return select(vec2(1.0, 0.0), vec2(0.0, 1.0), isCursor) * brightness; + return vec3( + select(vec2(1.0, 0.0), vec2(0.0, 1.0), isCursor) * base, + glint + ); } fn getSymbolUV(symbol : i32) -> vec2 { @@ -442,11 +449,9 @@ fn getSymbol(cellUV : vec2, index : i32) -> vec2 { var cell = cells_RO.cells[gridIndex]; var brightness = getBrightness( - cell.raindrop.r, - cell.raindrop.g, - input.quadDepth, - cell.effect.r, - cell.effect.g + cell.raindrop, + cell.effect, + input.quadDepth ); var symbol = getSymbol(uv, i32(cell.symbol.r)); @@ -464,7 +469,7 @@ fn getSymbol(cellUV : vec2, index : i32) -> vec2 { 1.0 ); } else { - output.color = vec4(brightness * symbol.r, brightness.r * symbol.g, 0.0); + output.color = vec4(brightness.rg * symbol.r, brightness.b * symbol.g, 0.0); } var highPassColor = output.color;