diff --git a/shaders/glsl/rainPass.frag.glsl b/shaders/glsl/rainPass.frag.glsl index a40b2c9..2dafbd2 100644 --- a/shaders/glsl/rainPass.frag.glsl +++ b/shaders/glsl/rainPass.frag.glsl @@ -22,11 +22,11 @@ float median3(vec3 i) { return max(min(i.r, i.g), min(max(i.r, i.g), i.b)); } -float getSymbolIndex(float glyphCycle) { +vec2 getSymbolUV(float glyphCycle) { float symbol = floor(glyphSequenceLength * glyphCycle); float symbolX = mod(symbol, glyphTextureColumns); float symbolY = ((glyphTextureColumns - 1.0) - (symbol - symbolX) / glyphTextureColumns); - return symbolY * glyphTextureColumns + symbolX; + return vec2(symbolX, symbolY); } void main() { @@ -56,7 +56,7 @@ void main() { // Unpack the values from the data texture vec4 glyph = volumetric ? vGlyph : texture2D(state, uv); float brightness = glyph.r; - float symbolIndex = getSymbolIndex(glyph.g); + vec2 symbolUV = getSymbolUV(glyph.g); float quadDepth = glyph.b; float effect = glyph.a; @@ -66,8 +66,7 @@ void main() { brightness = brightness * min(1.0, quadDepth); } - // resolve UV to position of glyph in MSDF texture - vec2 symbolUV = vec2(mod(symbolIndex, glyphTextureColumns), floor(symbolIndex / glyphTextureColumns)); + // resolve UV to cropped position of glyph in MSDF texture vec2 glyphUV = fract(uv * vec2(numColumns, numRows)); glyphUV -= 0.5; glyphUV *= clamp(1.0 - glyphEdgeCrop, 0.0, 1.0); diff --git a/shaders/wgsl/rainRenderPass.wgsl b/shaders/wgsl/rainRenderPass.wgsl index d662b02..f557434 100644 --- a/shaders/wgsl/rainRenderPass.wgsl +++ b/shaders/wgsl/rainRenderPass.wgsl @@ -76,9 +76,9 @@ struct VertInput { struct VertOutput { [[builtin(position)]] Position:vec4; - [[location(0)]] UV:vec2; - [[location(1)]] Channel:vec3; - [[location(2)]] Glyph:vec4; + [[location(0)]] uv:vec2; + [[location(1)]] channel:vec3; + [[location(2)]] glyph:vec4; }; struct FragOutput { @@ -147,17 +147,84 @@ fn wobble(x:f32) -> f32 { return VertOutput( pos, cornerPosition, - vec3(0.0), // channel - vec4(0.0) // glyph + vec3(1.0), // channel + vec4(1.0) // glyph ); } // Fragment shader -[[stage(fragment)]] fn fragMain(input: VertOutput) -> FragOutput { - var color:vec4 = textureSample(msdfTexture, msdfSampler, input.UV / f32(msdf.glyphTextureColumns)); - - return FragOutput( - color - ); +fn median3(i:vec3) -> f32 { + return max(min(i.r, i.g), min(max(i.r, i.g), i.b)); +} + +fn getSymbolUV(glyphCycle:f32) -> vec2 { + var symbol = i32(f32(msdf.glyphSequenceLength) * glyphCycle); + var symbolX = symbol % msdf.glyphTextureColumns; + var symbolY = ((msdf.glyphTextureColumns - 1) - (symbol - symbolX) / msdf.glyphTextureColumns); + return vec2(f32(symbolX), f32(symbolY)); +} + +[[stage(fragment)]] fn fragMain(input: VertOutput) -> FragOutput { + + var uv = input.uv; + + // In normal mode, derives the current glyph and UV from vUV + if (config.volumetric == 0) { + if (config.isPolar == 1) { + // Curved space that makes letters appear to radiate from up above + uv = (uv - 0.5) * 0.5; + uv.y = uv.y - 0.5; + var radius = length(uv); + var angle = atan2(uv.y, uv.x) / (2.0 * PI) + 0.5; // atan? + uv = vec2(fract(angle * 4.0 - 0.5), 1.5 * (1.0 - sqrt(radius))); + } else { + // Applies the slant and scales space so the viewport is fully covered + uv = vec2( + (uv.x - 0.5) * config.slantVec.x + (uv.y - 0.5) * config.slantVec.y, + (uv.y - 0.5) * config.slantVec.x - (uv.x - 0.5) * config.slantVec.y + ) * config.slantScale + 0.5; + } + uv.y = uv.y / config.glyphHeightToWidth; + } + + // Unpack the values from the data texture + var glyph:vec4; + if (config.volumetric == 1) { + glyph = input.glyph; + } else { + glyph = vec4(1.0); // TODO: texture2D(state, uv); + } + var brightness = glyph.r; + var symbolUV = getSymbolUV(glyph.g); + var quadDepth = glyph.b; + var effect = glyph.a; + + brightness = max(effect, brightness); + // In volumetric mode, distant glyphs are dimmer + if (config.volumetric == 1) { + brightness = brightness * min(1.0, quadDepth); + } + + // resolve UV to cropped position of glyph in MSDF texture + var glyphUV = fract(uv * vec2(f32(config.numColumns), f32(config.numRows))); + glyphUV = glyphUV - 0.5; + glyphUV = glyphUV * clamp(1.0 - config.glyphEdgeCrop, 0.0, 1.0); + glyphUV = glyphUV + 0.5; + var msdfUV = (glyphUV + symbolUV) / f32(msdf.glyphTextureColumns); + + // MSDF: calculate brightness of fragment based on distance to shape + var dist = textureSample(msdfTexture, msdfSampler, msdfUV).rgb; + var sigDist = median3(dist) - 0.5; + var alpha = clamp(sigDist / fwidth(sigDist) + 0.5, 0.0, 1.0); + + var output:FragOutput; + + if (config.showComputationTexture == 1) { + output.color = vec4(glyph.rgb * alpha, 1.0); + } else { + output.color = vec4(input.channel * brightness * alpha, 1.0); + } + + return output; }