Skip to content

Commit

Permalink
feat: enhance shader (#33)
Browse files Browse the repository at this point in the history
* feat: enhance dithering

* feat: enhance scanline
  • Loading branch information
LuciNyan committed May 2, 2024
1 parent 75e52bb commit b794e29
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 21 deletions.
23 changes: 12 additions & 11 deletions packages/pixel-profile/src/shaders/dithering.ts
Original file line number Diff line number Diff line change
Expand Up @@ -302,43 +302,44 @@ const saturationSteps = 4
function hueDistance(h1: number, h2: number): number {
const diff = Math.abs(h1 - h2)

return Math.min(Math.abs(1 - diff), diff)
return diff < 0.5 ? diff : 1 - diff
}

function lightnessStep(l: number): number {
return Math.floor(0.5 + l * lightnessSteps) / lightnessSteps
return Math.round(l * lightnessSteps) / lightnessSteps
}

function saturationStep(s: number): number {
return Math.floor(0.5 + s * saturationSteps) / saturationSteps
return Math.round(s * saturationSteps) / saturationSteps
}

function closestColors(hue: number): [[number, number, number], [number, number, number]] {
let closest: [number, number, number] = [-2, 0, 0]
let secondClosest: [number, number, number] = [-2, 0, 0]
let minDist = Infinity
let secondMinDist = Infinity

for (const color of PALETTE_256) {
const tempDistance = hueDistance(color[0], hue)
if (tempDistance < hueDistance(closest[0], hue)) {
const dist = hueDistance(color[0], hue)
if (dist < minDist) {
secondClosest = closest
secondMinDist = minDist
closest = color
} else if (tempDistance < hueDistance(secondClosest[0], hue)) {
minDist = dist
} else if (dist < secondMinDist) {
secondClosest = color
secondMinDist = dist
}
}

return [closest, secondClosest]
}

function dither(pos: [number, number], color: [number, number, number]): [number, number, number] {
const x = Math.floor(pos[0] % 8)
const y = Math.floor(pos[1] % 8)
const index = x + y * 8

const index = (pos[0] & 7) + ((pos[1] & 7) << 3)
const limit = (ditherTable[index] + 1) / 64 + BIAS_256

const [closest, secondClosest] = closestColors(color[0])

const hueDiff = hueDistance(color[0], closest[0]) / hueDistance(secondClosest[0], closest[0])

const l1 = lightnessStep(Math.max(color[2] - 0.125, 0))
Expand Down
4 changes: 3 additions & 1 deletion packages/pixel-profile/src/shaders/pixelate.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import { render } from '../renderer'

export function pixelate(source: Buffer, width: number, height: number, blockSize: number): Buffer {
const halfBlockSize = blockSize / 2

return render(source, width, height, (coords, texture) => {
const x = Math.floor(coords[0] / blockSize)
const y = Math.floor(coords[1] / blockSize)

return texture([x * blockSize + blockSize / 2, y * blockSize + blockSize / 2])
return texture([x * blockSize + halfBlockSize, y * blockSize + halfBlockSize])
})
}
20 changes: 11 additions & 9 deletions packages/pixel-profile/src/shaders/scanline.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,22 @@
import { render, RGBA } from '../renderer'
import { render } from '../renderer'

const scanlineIntensity = 0.15
const scanlineThickness = 3
const scanlineBrightness = 1 - scanlineIntensity

export function scanline(source: Buffer, width: number, height: number): Buffer {
return render(source, width, height, (coords, texture) => {
const onScanline = coords[1] % scanlineThickness === 0

const samplerColor = texture(coords)

const scanlineBrightness = onScanline ? 1 - scanlineIntensity : 1
if (coords[1] % scanlineThickness === 0) {
return [
samplerColor[0] * scanlineBrightness,
samplerColor[1] * scanlineBrightness,
samplerColor[2] * scanlineBrightness,
samplerColor[3]
]
}

return multiply(samplerColor, scanlineBrightness)
return samplerColor
})
}

function multiply(color: RGBA, factor: number): RGBA {
return [color[0] * factor, color[1] * factor, color[2] * factor, color[3]]
}

0 comments on commit b794e29

Please sign in to comment.