Community이미지github.com

Stankjedi/poku-pixel-fx

로컬 Poku Pixel FX 라이브러리를 사용하여 픽셀 아트 효과와 스프라이트 시트를 제작하고 개선합니다. 게임 VFX, 애니메이션 및 엔진 내보내기에 사용하세요.

poku-pixel-fx란 무엇인가요?

POKU Pixel FX는 Patch의 PixelFX를 기반으로 한 TypeScript 기반 오픈소스 포크/파생 프로젝트입니다. 한국어 현지화를 지원하며, 각 효과는 단일 TypeScript 파일로 작성되어 컬러(불투명, 디더링 또는 반투명 픽셀)와 라이트(가산 글로우) 두 개의 버퍼로 구성됩니다. Node.js 18 이상이 필요하며 ffmpeg는 GIF/MP4 프리뷰에 선택 사항입니다. Claude Code, Cursor, Codex 등 AI 에이전트와 함께 사용하여 게임 VFX, 애니메이션 및 엔진 내보내기용 스프라이트 시트를 제작하고 개선할 수 있습니다. Hugo Duprez의 '코드는 점토' 접근법을 따라 한 번의 프롬프트 대신 드래프트를 반복 렌더링하고 판단하며 개선합니다. 기존 효과 검색(list.mjs), 옵션 조정(팔레트, 시드, 각도 등), 새로운 효과 제작(AUTHORING.md, QUALITY.md 참조), 액트(act)를 통한 캐릭터 동작 구현, 스프라이트 시트 내보내기 등 다양한 워크플로우를 지원하며, 모든 엔진(Godot, Unity, Phaser 등)과 호환됩니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Stankjedi/poku-pixel-fx/tree/HEAD/skills/poku-pixel-fx

Installed? Explore more 이미지 skills: steipete/songsee, affaan-m/frontend-design, mattpocock/improve-codebase-architecture · View all 6 →

즐겨 사용하는 AI에게 물어보기

이 에이전트 스킬이 미리 로드된 새 채팅을 엽니다.

문서

poku-pixel-fx은(는) 무엇을 하나요?

POKU Pixel FX는 PixelFX by Patch의 한국어 현지화된 TypeScript 기반 오픈소스 포크/파생 프로젝트입니다. 별도의 리포지토리로 유지 관리되며 GitHub 네트워크 포크 링크는 없습니다. 업스트림 MIT 라이선스는 Patch와 Hugo Duprez에게 저작권을 부여합니다. LICENSE와 NOTICE.md의 저작권 및 저작자 표시 고지를 유지하세요.

Node.js 18 이상이 필요합니다. ffmpeg는 GIF 및 MP4 프리뷰에 선택 사항입니다.

코드로서의 픽셀 아트 효과. 각 효과는 src/fx/<카테고리>/<이름>.ts의 한 파일로, 두 개의 버퍼에 그립니다: 컬러(픽셀: 불투명, 디더링 또는 진정한 반투명)와 라이트(가산 글로우). 이미지가 없으므로 효과를 실시간으로 재생하고, 색상을 변경하고, 미러링하고, 시드를 재설정하고, 모든 엔진용 스프라이트 시트로 렌더링할 수 있습니다.

방법은 Hugo Duprez의 (How to make (good) pixel art effects with Claude): 코드는 점토이고, 자신의 눈을 믿고, 참고 자료를 활용하세요. 한 번의 프롬프트로는 평범한 효과가 만들어집니다. 렌더링하고, 보고, 개선하는 드래프트가 좋은 결과를 만듭니다.

시작하기 전에

  1. package.json과 tools/render.mts가 포함된 Poku Pixel FX 체크아웃에서 작업하세요. 없으면 사용자의 선택한 프로젝트 또는 작업 공간에 공개 라이브러리를 가져옵니다: git clone https://github.com/Stankjedi/poku-pixel-fx.git. 스킬 파일만으로는 효과 라이브러리가 포함되지 않습니다. 다른 사람의 기계별 경로를 절대 사용하지 마세요. 필요할 때 npm ci로 체크아웃의 종속성을 설치하세요. 이미 설치되어 있으면 반복하지 마세요.
  2. 도구나 갤러리를 사용하기 전에 npm run build를 실행하세요. 컴파일러는 런타임 모듈을 build/로, CLI 도구를 build-tools/로 내보냅니다.
  3. 실행 확인: node build-tools/tools/render.mjs fire/torch는 records/fire/torch/contact.png를 작성합니다. 이미지 읽기 도구로 해당 PNG를 여세요. 이 콘택트 시트는 앞으로 모든 효과를 확인하는 방법입니다.

1. 기존 효과를 먼저 찾으세요

node build-tools/tools/list.mjs <단어>는 ID, 이름, 태그 및 설명을 검색합니다(node build-tools/tools/list.mjs frost, node build-tools/tools/list.mjs slash loop). docs/CATALOG.md는 모든 것을 카테고리별로 나열합니다. 후보를 렌더링하고 선택하기 전에 살펴보세요. 대부분의 요청은 다른 옵션이 있는 기존 효과입니다:

  • palette: 메인 램프, 어두운 것부터 밝은 것까지, 16진수 문자열. src/core/color.ts의 모든 PAL 램프(fire ember lava smoke dust ice water electric volt poison holy heal arcane shadow blood earth stone gold leaf wood metal bone neon cyber matrix candy night) 또는 자신의 것. 파란 불은 {"palette": PAL.ice}입니다.
  • seed: 다르지만 동등한 결과를 위해; flip: 왼쪽을 향하게; angle: 회전; light (0..1+): 글로우 강도; 각 효과의 고유한 노브는 meta.options (size, count, radius, text, height...)에 있습니다.
  • 코드 편집 없이 옵션 시도: node build-tools/tools/render.mjs fire/torch --opts '{"palette":["#102","#215","#43a","#8cf","#fff"]}'.

2. 게임에 적용하세요

JS 또는 TS의 Canvas 또는 WebGL 게임 (일반 canvas, Phaser, PixiJS, Kaplay, three.js): 코드를 직접 사용하세요. 종속성이 없습니다. src/core와 필요한 효과 파일을 복사하거나 리포지토리에 의존하세요.

import { createFrame, clearFrame, createFx, composite } from "poku-pixel-fx";   // src/core/index.ts
import * as frostNova from "poku-pixel-fx/fx/ice/frost-nova";                   // src/fx/ice/frost-nova.ts

const frame = createFrame(320, 180);            // 게임의 픽셀 해상도; ox, oy는 카메라로 스크롤
const img = new ImageData(320, 180);
const fx = createFx(frostNova, { x: hero.x, y: hero.y, flip: hero.facing < 0 });

// 매 틱마다
fx.update(dt);
clearFrame(frame);
fix.draw(frame, "back");    // 캐릭터 뒤에 오는 것
drawCharacters();          // 자신의 스프라이트, 또는 직접 frame.color에 그리기
fx.draw(frame, "front");
composite(frame, img.data, background);   // 배경 위에 컬러 + 라이트; 또는 null은 투명
ctx.putImageData(img, 0, 0);              // 그런 다음 image-rendering: pixelated로 캔버스 크기 조정
if (fx.done()) removeIt();               // 일회성은 저절로 끝남; fx.stop()은 루프를 페이드 아웃

여러 효과가 하나의 프레임을 공유할 수 있습니다. WebGL 엔진에서는 매 프레임 합성된 RGBA를 텍스처에 업로드하거나, 아래와 같이 스프라이트 시트로 한 번 렌더링하고 다른 애니메이션처럼 재생하세요.

모든 엔진 (Godot, Unity, GameMaker, Defold, LÖVE, Bevy, Construct): 스프라이트 시트를 내보냅니다. node build-tools/tools/render.mjs ice/frost-nova --sheet는 records/ice/frost-nova/frost-nova.png (그리드의 투명 프레임)와 frost-nova.json (Aseprite 스타일 프레임, Phaser의 아틀라스 로더, Godot 및 Unity Aseprite 임포터 및 대부분의 도구에서 읽을 수 있음; meta.pokuFx에는 fps, loop, 프레임 크기, 열 및 피벗이 있음)을 작성합니다. 피벗을 meta.pokuFx.pivot (효과의 원점, 예: 발)으로 설정하고, 최근접 이웃 필터링과 압축 없이 가져오고, meta.pokuFx.fps로 재생하세요. 글로우는 색상이 있는 알파로 시트에 베이킹되며, 어두운 장면에서는 가산으로 읽힙니다. 밝은 장면의 경우 색상을 변경한 버전을 렌더링하거나 효과를 어두운 레이어에 유지하세요.

전체 라이브러리의 경우: node build-tools/tools/render.mjs <카테고리> --sheet는 전체 카테고리를 처리합니다.

공격에는 그 뒤에 몸체가 필요합니다. 효과만으로는 스티커처럼 보입니다. 캐릭터가 있는 효과는 act를 전달합니다: 몸체가 움직일 때, 멈출 때, 대상이 어떻게 반응하는지. 게임이 어떻게 구축되었든 사용하세요:

  • 기본 캐릭터 사용: createFx 대신 createAct(slash, { x, y }). act.update(dt), act.draw(frame), 그리고 act.shake로 그림을 던집니다. 멈춤 중에는 자동으로 가만히 있습니다. node build-tools/tools/act.mjs <id> --sheet는 모든 것을 스프라이트 시트로 베이킹합니다.
  • 게임 자체 캐릭터 사용: 타이밍을 읽습니다. slash.act 또는 시트 JSON의 meta.pokuFx.act (windup, recovery, hits와 t 및 freeze). 효과 전 windup초 동안 캐릭터의 공격 애니메이션을 재생하고, 각 히트 시 효과와 캐릭터 모두 업데이트를 freeze초 동안 중지합니다. 호스트 측 히트스탑은 act가 있거나 없이 모든 효과에서 작동합니다.

src/fx/moves/에는 효과에서 연결된 전체 공격이 있습니다. 효과가 아닌 동작을 요청할 때 거기서 시작하세요.

3. 새 효과 만들기

먼저 docs/AUTHORING.md를 읽으세요: 이것은 계약입니다(meta, 순수 효과를 위한 draw(p, t, o) 또는 시뮬레이션 효과를 위한 create(o), 로컬 좌표, 매끄러운 루프, 빈 상태로 끝나기), 도구 키트, 페인터 API 및 품질 기준. docs/QUALITY.md도 읽으세요. shadow/spatial-severance를 깔끔한 곡선, 정제된 입자의 참조로 취급하고, 모든 효과에 강요할 스타일이 아닙니다. 새로운 효과는 적절한 경우 공유 리본, 궤적 트레일, 엔벨로프 및 경로 조명 도우미를 사용해야 합니다. 픽셀 팔레트를 유지하고 네이티브 크기 실루엣, 임팩트 타이밍, 네거티브 스페이스 및 투명도를 검사하세요. 자동화된 테스트는 예술적 품질을 보장하지 않습니다. 임팩트를 포함하는 효과의 경우 docs/IMPACT_INTERACTIONS.md도 읽으세요: 하나의 접촉 설명자(시간, 로컬 포인트, 법선, 재질)를 작성하고, 그로부터 모양별 응답 및 선택적 장면 피드백을 파생하세요. 지면/대상 반응, 2차 충돌 및 정착을 검토하세요. 모든 재질에 동일한 충격 링, 돌 파편 또는 화면 흔들림을 추가하지 마세요. 축소된 동작 및 고정 피벗 투명 내보내기를 유지하세요. 그런 다음:

  1. 한 줄로 말하세요 아트 디렉션과 함께: 무엇인지, 어떻게 움직이는지, 팔레트, 타이밍. "서리 신성한 폭발: 발에서 바깥쪽으로 고리가 결정을 분출하며, 중앙에 흰색 섬광, 파편이 회전하며 떨어져 나가고, 바닥은 서리로 덮여 희미해짐."
  2. 라이브러리에서 참조 찾기: node build-tools/tools/list.mjs <단어>, 그런 다음 가장 가까운 두세 개의 효과 파일을 읽고 기술을 차용하세요(src/core/sim.ts의 Particles 및 Bits는 스파크, 연기 및 파편용, p.disc는 반투명 볼륨용, cycle은 매끄러운 입자용, tileFbm 스크롤은 불과 물용). 로컬 라이브러리 참조를 품질 기준으로 사용하세요. 외부 참조는 선택 사항이며 네트워크 액세스가 필요합니다.
  3. 초안 작성. node build-tools/tools/new.mjs <카테고리>/<이름> (--loop 추가 시 루프)은 작업 파일을 제공합니다. 방향이 열려 있으면 3~5개의 진정으로 다른 초안을 작성하세요(<이름>-a.ts .. -e.ts), 모두 렌더링하고(node build-tools/tools/render.mjs "<카테고리>/<이름>-*") 선택하기 전에 모든 콘택트 시트를 보세요. 사용자가 근처에 있으면 가장 강력한 두세 개를 보여주세요(--gif는 공유할 애니메이션을 만듭니다). 소스 파일을 변경한 후 렌더링하기 전에 다시 빌드하세요.
  4. 보고, 판단하고, 수정하세요. 렌더링하고, records/<id>/contact.png를 열고, 까다로운 픽셀 아티스트처럼 판단하세요. 최악의 것을 고치고, 다시 렌더링하세요. 최소 3라운드; 걸작은 더 오래 걸립니다. --all은 모든 프레임을 보여주고, --mp4는 전체 속도로 동작을 보여줍니다.
  5. 액트로 연출하세요 캐릭터가 관련된 경우: export const act 추가 ("Acts" 참조 docs/AUTHORING.md), t = 0 전에 윈드업, 릴리스 프레임에서 포즈 변경, 접촉 시 멈춤 및 회복. node build-tools/tools/act.mjs <id>는 연속적인 12fps 단계를 보여줍니다: 콘택트 시트 샘플이 아닌 이러한 단계와 --mp4에서 동작을 판단하세요.
  6. 확인하세요. node build-tools/tools/check.mjs <id>는 캔버스 외부 그리기, 빈 상태로 끝나지 않는 일회성, 루프 이음새, 시드되지 않은 무작위성 및 느린 프레임, 그리고 액트에서: 순서가 잘못된 키, 알 수 없는 포즈 필드 및 순간이동하는 손을 잡아냅니다. 깨끗하게 통과할 때까지 수정하세요. 유지하지 않은 초안은 삭제하세요.

찾아야 할 것과 일반적인 수정:

보이는 것수정 방법
1배율에서 뭉개짐더 적은 색상, 명확한 실루엣, 하나의 초점, 더 큰 모양
얼룩: 모양 내부의 잡음 픽셀잡음 임계값 낮추기, at()으로 양자화, 작은 모양에 잡음 없음
뜨는 느낌, 펀치 없음빠르게 들어오고 느리게 나감(ease.outQuart/outExpo), 1~2프레임 흰색 영웅 프레임, 더 짧은 총 시간
뻣뻣하거나 기계적임모든 입자 다양화(크기, 속도, 지연, 수명), 2차 동작 추가(스파크, 연기, 파편)
색상이 바랜 느낌글로우 줄이기(k 0.2~0.5), 더 어두운 가장자리 단계, 가장 뜨거운 코어에만 흰색 유지
평평함한쪽에서 빛: 더 밝은 왼쪽 위, 더 어두운 오른쪽 아래 단계; 베이스에 더 어두운 램프 단계
부드러운 그라데이션, 벡터 느낌컬러에서 하드 램프 단계; 부드러움은 라이트와 반투명 연기에만 허용
연기여야 할 곳에 체커보드SMOKE, VAPOUR 또는 DUST 입자, 또는 p.disc: 진정한 반투명, 위에 조명
루프가 감길 때 이음새cycle, loopNoise(phase), 전체 셀 tileNoise 스크롤, sin(phase * TAU * n)
갑자기 사라지는 일회성t = duration 전에 축소, 디더 아웃 또는 떨어져 나가게 하기
죽은 캐릭터의 훌륭한 효과act 부여: 윈드업, 릴리스 포즈, 접촉 시 멈춤, 반응하는 대상, 회복
액트가 무게감 없음타격 반대 방향으로 윈드업, 더 긴 멈춤(최대 0.2초), 더 큰 실루엣 변화, 흔들림
히트가 동기화되지 않음히트 키를 눈으로 맞춘 시간이 아닌 효과 자체 상수로 이동
무기를 잘못 잡음팔꿈치에 굽힘 유지, 샤프트는 가슴 앞; 스윙 시 블레이드가 손에 뒤쳐짐; 팔은 약 15px에 도달하며 늘어나지 않으므로 몸체를 스텝 인
팔이 교차하거나 포즈가 평평함3/4 시점으로 우리를 향함: 열린 팔의 경우 가까운 손은 왼쪽(fx < 0), 먼 손은 오른쪽, turn: 1 사용; yaw가 실제로 회전

방향성 효과는 오른쪽을 향하고, 지면 효과는 y = 0에 서 있고, 액터 효과는 o.actor(24 x 38 기본 캐릭터의 마스크 및 픽셀)를 래핑하며, 아무것도 Math.random을 사용하지 않습니다. 일반적인 모티프는 괜찮습니다. 특정 게임의 스프라이트, 캐릭터 또는 로고를 재현하지 마세요.

4. JS 대신 네이티브 코드

게임이 JS를 실행할 수 없고 스프라이트 시트만으로 충분하지 않은 경우(움직이는 대상을 따라가는 효과, 런타임에 인스턴스별 색상이 필요한 경우) 효과를 포팅하세요. 순수 효과는 시간의 함수입니다. 시뮬레이션된 효과는 src/core/sim.ts의 입자를 단계별로 실행합니다. 2버퍼 아이디어, 디더링된 알파를 위한 4x4 Bayer 임계값 및 팔레트 램프 조회를 유지하세요. JS 원본과 포팅 버전을 나란히 렌더링하여 일치하는지 확인하세요.

코어, 모든 효과, 갤러리 및 CLI는 TypeScript 소스입니다. 사용 전에 빌드하세요. .ts 효과를 만들거나 변경한 후 렌더링하기 전에 다시 빌드하세요. 갤러리와 CLI 검색은 한국어와 영어를 지원합니다. 한국어 텍스트는 시스템 글꼴로 대체됩니다. 엔진 네이티브 작업은 docs/NATIVE_MIGRATION.md를 참조하세요. 네이티브 런타임이 존재한다고 주장하지 마세요.

결과 공유

사용자가 공개 공유를 요청할 때 로컬 체크아웃을 사용하고 npm run build를 실행한 후 npm run share -- <카테고리>/<효과>를 실행하세요. 명령은 새로운 records/share/ 폴더에 투명 PNG와 Poku JSON을 렌더링하고, 현재 사이트 크기 및 애니메이션 제한을 확인하며, 절대 파일 경로와 공유 페이지를 출력합니다. 게시하거나 로그인하지 않습니다.

https://poku-pixel-fx.stankjedi.chatgpt.site/shared를 열고, 필요하면 ChatGPT로 로그인한 후 페이지의 업로드 흐름을 따르세요. 공유 양식에서 일치하는 PNG와 JSON을 함께 선택하고, 필요한 제목과 태그를 입력한 후 업로더가 권리 선언을 확인하면 제출하세요. 여러 작품의 경우 벌크 섹션은 일치하는 PNG와 JSON 파일 이름을 허용합니다. 사용자가 요청한 아트워크를 사용하고 브라우저의 업로드 및 확인 규칙을 준수하세요. ID 헤더를 제조하거나, 자격 증명을 획득/복사하거나, 사용자의 확인 없이 사용자의 법적 권리를 주장하지 마세요. 게시를 주장하기 전에 갤러리에서 성공 메시지와 결과 항목을 확인하세요. 사이트는 계정당 할당량을 적용할 수 있습니다. 소프트웨어를 재배포할 때 LICENSE, NOTICE 및 타사 저작권 및 허가 고지를 유지하세요.

관련 스킬