Skip to content

Commit

Permalink
feat: scanline (#23)
Browse files Browse the repository at this point in the history
  • Loading branch information
LuciNyan committed Apr 4, 2024
1 parent afccff3 commit 6fb7097
Show file tree
Hide file tree
Showing 15 changed files with 93 additions and 5 deletions.
2 changes: 2 additions & 0 deletions packages/pixel-profile/src/cards/stats.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { addBorder, curve, pixelate } from '../shaders'
import { scanline } from '../shaders/scanline'
import {
AVATAR_SIZE,
CARD_SIZE,
Expand Down Expand Up @@ -147,6 +148,7 @@ export async function renderStats(stats: Stats, options: Options = {}): Promise<
let { pixels } = await getPixelsFromPngBuffer(pngBuffer)

if (screenEffect) {
pixels = scanline(pixels, width, height)
pixels = curve(pixels, width, height)
}

Expand Down
10 changes: 5 additions & 5 deletions packages/pixel-profile/src/shaders/border.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,24 +24,24 @@ export function addBorder(

const frameWidth = frameWidthRatio * width

const rgba: RGBA = texture2D([uv[0], uv[1]])
const samplerColor: RGBA = texture2D(uv)

const count =
Number(x < frameWidth) + Number(y < frameWidth) + Number(x > maxX - frameWidth) + Number(y > maxY - frameWidth)

if (count !== 0) {
if (enabledTransparentBorder) {
rgba[3] = 128
samplerColor[3] = 128
}

if (count === 2 && enabledCornerRemoval) {
rgba[3] = 0
samplerColor[3] = 0
}

return rgba
return samplerColor
}

return rgba
return samplerColor
},
{
textureFilter: TEXTURE_FILTER.NEAREST
Expand Down
22 changes: 22 additions & 0 deletions packages/pixel-profile/src/shaders/scanline.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import { render, RGBA } from '../renderer'

const scanlineIntensity = 0.15
const scanlineThickness = 3

export function scanline(source: Buffer, width: number, height: number): Buffer {
return render(source, width, height, (uv, texture2D) => {
const scanlinePosition = Math.floor(uv[1] * height)

const onScanline = scanlinePosition % scanlineThickness === 0

const samplerColor = texture2D(uv)

const scanlineBrightness = onScanline ? 1 - scanlineIntensity : 1

return multiply(samplerColor, scanlineBrightness)
})
}

function multiply(color: RGBA, factor: number): RGBA {
return [color[0] * factor, color[1] * factor, color[2] * factor, color[3]]
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
64 changes: 64 additions & 0 deletions packages/pixel-profile/test/theme.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,3 +66,67 @@ describe('Theme', () => {
expect(png).toMatchImageSnapshot()
})
})

describe('Theme with screen effect', () => {
it('Render card with summer theme and custom color', async () => {
const png = await renderStats(stats, { theme: 'summer', color: 'yellow', screenEffect: true })
expect(png).toMatchImageSnapshot()
})

it('Render card with summer theme and custom background', async () => {
const png = await renderStats(stats, { theme: 'summer', background: 'black', screenEffect: true })
expect(png).toMatchImageSnapshot()
})

it('Render card with summer theme', async () => {
const png = await renderStats({ ...stats, avatarUrl: BLUE_AVATAR }, { theme: 'summer', screenEffect: true })
expect(png).toMatchImageSnapshot()
})

it('Render card with blue_chill theme', async () => {
const png = await renderStats(stats, { theme: 'blue_chill', screenEffect: true })
expect(png).toMatchImageSnapshot()
})

it('Render card with rainbow theme', async () => {
const png = await renderStats(
{ ...stats, avatarUrl: KITTEN_AVATAR },
{ theme: 'rainbow', pixelateAvatar: false, screenEffect: true }
)
expect(png).toMatchImageSnapshot()
})

it('Render card with monica theme', async () => {
const png = await renderStats({ ...stats, avatarUrl: PURPLE_AVATAR }, { theme: 'monica', screenEffect: true })
expect(png).toMatchImageSnapshot()
})

it('Render card with lax theme', async () => {
const png = await renderStats({ ...stats, avatarUrl: ORANGE_AVATAR }, { theme: 'lax', screenEffect: true })
expect(png).toMatchImageSnapshot()
})

it('Render card with journey theme', async () => {
const png = await renderStats(
{ ...stats, avatarUrl: DARK_GREEN_AVATAR },
{ theme: 'journey', pixelateAvatar: false, screenEffect: true }
)
expect(png).toMatchImageSnapshot()
})

it('Render card with fuji theme', async () => {
const png = await renderStats(
{ ...stats, avatarUrl: LUCI_AVATAR },
{ theme: 'fuji', pixelateAvatar: false, screenEffect: true }
)
expect(png).toMatchImageSnapshot()
})

it('Render card with road trip theme', async () => {
const png = await renderStats(
{ ...stats, avatarUrl: PIXEL_DOG_AVATAR },
{ theme: 'road_trip', pixelateAvatar: false, screenEffect: true }
)
expect(png).toMatchImageSnapshot()
})
})

0 comments on commit 6fb7097

Please sign in to comment.