Skip to content

Commit

Permalink
perf: enhance glow rendering speed (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
LuciNyan authored Sep 10, 2024
1 parent 108a6d5 commit e90c965
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 14 deletions.
4 changes: 2 additions & 2 deletions packages/pixel-profile/src/renderer/common.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,11 @@ export type Texture = (coords: PixelCoords) => RGBA
export type FragShader = (coords: PixelCoords, texture: Texture) => RGBA

export function coordsToIndex(x: number, y: number, width: number): number {
return (y * width + x) * 4
return y * width + x
}

export function coordsToPixel(source: Buffer, x: number, y: number, width: number): RGBA {
const index = coordsToIndex(x, y, width)
const index = coordsToIndex(x, y, width) * 4

return [source[index], source[index + 1], source[index + 2], source[index + 3]]
}
2 changes: 1 addition & 1 deletion packages/pixel-profile/src/renderer/render.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function render(
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const rgba = fragShader([x, y], texture)
const index = coordsToIndex(x, y, width)
const index = coordsToIndex(x, y, width) * 4
target[index] = rgba[0]
target[index + 1] = rgba[1]
target[index + 2] = rgba[2]
Expand Down
32 changes: 21 additions & 11 deletions packages/pixel-profile/src/shaders/glow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,35 +8,45 @@ 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)
const size = width * height
const bufferSize = (1 + 4 + 4) * size
const sharedBuffer = new ArrayBuffer(bufferSize)
const memoResult = new Uint8Array(sharedBuffer, 0, size)
const memoSampledColor = new Uint8Array(sharedBuffer, size, size * 4)
const memoLuminance = new Float32Array(sharedBuffer, size * 5, size)

return render(
source,
width,
height,
(uv, texture2D) => {
const originalColor = texture2D(uv)

let glowColor: Vec3 = [0, 0, 0]
let n = 0

const _uv: Vec2 = [0, 0]

for (let i = -radius; i <= radius; i++) {
for (let j = -radius; j <= radius; j++) {
const _uv: Vec2 = [uv[0] + i, uv[1] + j]
_uv[0] = uv[0] + i
_uv[1] = uv[1] + j
const key = coordsToIndex(_uv[0], _uv[1], width)

if (!memo[key]) {
if (memoResult[key] === undefined) {
continue
}

if (memoResult[key] === 0) {
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
}
memoResult[key] = luminance > threshold ? 1 : 2
memoSampledColor.set(sampledColor, key * 4)
memoLuminance[key] = luminance
}

if (memo[key].result) {
const { sampledColor, luminance } = memo[key]
if (memoResult[key] === 1) {
const sampledColor: RGBA = memoSampledColor.subarray(key * 4, key * 4 + 4) as unknown as RGBA
const luminance = memoLuminance[key]
const distSquared = i * i + j * j
const weight = Math.exp(-distSquared / radiusSquared) ** 3
const factor = weight * intensity * luminance ** 5
Expand Down

0 comments on commit e90c965

Please sign in to comment.