From 64cfeb3169311472afc7881548580e870ea231c1 Mon Sep 17 00:00:00 2001 From: LuciNyan <22126563+LuciNyan@users.noreply.github.com> Date: Wed, 4 Sep 2024 14:47:44 +0800 Subject: [PATCH] perf: enhance glow rendering speed (#43) --- packages/pixel-profile/src/shaders/glow.ts | 62 +++++++--------------- 1 file changed, 20 insertions(+), 42 deletions(-) diff --git a/packages/pixel-profile/src/shaders/glow.ts b/packages/pixel-profile/src/shaders/glow.ts index 037a2dc..eb434df 100644 --- a/packages/pixel-profile/src/shaders/glow.ts +++ b/packages/pixel-profile/src/shaders/glow.ts @@ -1,10 +1,11 @@ import { coordsToIndex, render, RGBA } from '../renderer' -import { add2, Vec2 } from '../utils' -import { add3, divide3, dot3, mix3, Vec3 } from '../utils/math' +import { Vec2 } from '../utils' +import { add3, divide3, mix3, Vec3 } from '../utils/math' const radius = 5 const intensity = 0.7 const threshold = 0.8 +const radiusSquared = radius * radius * 2 export function glow(source: Buffer, width: number, height: number): Buffer { const memo: { result: boolean; sampledColor: RGBA; luminance: number }[] = new Array(width * height) @@ -21,57 +22,34 @@ export function glow(source: Buffer, width: number, height: number): Buffer { for (let i = -radius; i <= radius; i++) { for (let j = -radius; j <= radius; j++) { - const _uv: Vec2 = add2(uv, [i, j]) + const _uv: Vec2 = [uv[0] + i, uv[1] + j] const key = coordsToIndex(_uv[0], _uv[1], width) - if (memo[key]) { - if (memo[key].result) { - const sampledColor = memo[key].sampledColor - const luminance = memo[key].luminance - const dist = length2([i, j]) - const weight = Math.pow(Math.exp((-dist * dist) / (2 * radius * radius)), 3) - glowColor = add3( - glowColor, - mix3(originalColor, sampledColor, weight * intensity * Math.pow(luminance, 5)) - ) - - n++ + if (!memo[key]) { + const sampledColor = texture2D(_uv) + const luminance = (sampledColor[0] * 0.2126 + sampledColor[1] * 0.7152 + sampledColor[2] * 0.0722) / 255 + memo[key] = { + result: luminance > threshold, + sampledColor, + luminance } - continue } - memo[key] = {} as any - const sampledColor = texture2D(_uv) - const luminance = dot3(sampledColor, [0.2126, 0.7152, 0.0722]) / 255 - if (luminance > threshold) { - const dist = length2([i, j]) - const weight = Math.pow(Math.exp((-dist * dist) / (2 * radius * radius)), 3) - glowColor = add3(glowColor, mix3(originalColor, sampledColor, weight * intensity * Math.pow(luminance, 5))) + if (memo[key].result) { + const { sampledColor, luminance } = memo[key] + const distSquared = i * i + j * j + const weight = Math.exp(-distSquared / radiusSquared) ** 3 + const factor = weight * intensity * luminance ** 5 + glowColor = add3(glowColor, mix3(originalColor, sampledColor, factor)) n++ - - memo[key].result = true - memo[key].sampledColor = sampledColor - memo[key].luminance = luminance - } else { - memo[key].result = false } } } - if (n === 0) { - return originalColor - } - - glowColor = divide3(glowColor, n) + if (n === 0) return originalColor - return [glowColor[0], glowColor[1], glowColor[2], 255] + return [...divide3(glowColor, n), 255] }, - { - textureFilter: 'NEAREST' - } + { textureFilter: 'NEAREST' } ) } - -function length2(v: Vec2): number { - return Math.sqrt(v[0] * v[0] + v[1] * v[1]) -}