Communitygithub.com

복셀 애니메이션

블록 조립 게임 같은 3D 장면과 애니메이션을 three.js, 절차적 픽셀 아트 텍스처, 독창적인 블록 캐릭터로 제작하고, 프레임 정확한 비디오(.mov 알파 채널 포함, .mp4) 또는 공유 가능한 HTML 페이지로 내보냅니다. 복셀 또는 블록 애니메이션, '블록 하나씩 쌓아 올리는' 장면, 과학 아이디어를 설명하는 블록 월드, 픽셀 아트 3D 인트로에 사용하세요.

복셀 애니메이션란 무엇인가요?

이 스킬은 기존 게임 애셋 없이도 블록 조립 게임 스타일의 3D 장면과 애니메이션을 제작할 수 있는 완전한 도구 키트를 제공합니다. 모든 텍스처는 런타임에 코드로 생성되며, 캐릭터는 독창적인 디자인으로 저작권 문제를 피할 수 있습니다. 출력물은 대화형이며 공유 가능한 단일 HTML 파일 또는 프레임 정확한 비디오(.mov, .mp4)로 제공됩니다. 주요 기능으로 절차적 텍스처, 섬 지형, 캐릭터 릭, 파티클, 폭발 및 조명 시스템이 포함된 복셀 키트가 있으며, 시간 기반 상태 머신을 사용한 스토리보드 타임라인을 지원합니다. Claude Code, Cursor, Codex와 같은 AI 코딩 에이전트와 호환되며, 사용자는 복셀 키트 API(VK.createApp, VK.block, VK.character 등)를 활용하여 반복 가능한 시드 기반 애니메이션을 제작할 수 있습니다. 또한 수학, 물리학, 화학 개념의 시각적 설명을 위한 '블록으로 설명하는 과학' 예제를 제공하며, 프레임 정확한 렌더링과 URL 매개변수(capture, alpha, clean 등)를 통한 다양한 내보내기 옵션을 지원합니다.

지원 대상✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/normix93/voxel-animations/tree/HEAD

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

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

문서

복셀 애니메이션은(는) 무엇을 하나요?

블록 조립 게임처럼 보이는 장면을, 실제 게임 애셋 없이 만듭니다. 모든 텍스처는 런타임에 코드로 생성되며 캐릭터는 독창적인 디자인입니다. 출력물은 하나의 독립적인 HTML 페이지(대화형, 공유 가능)이며, 요청 시 같은 페이지에서 프레임 정확한 비디오로 렌더링됩니다.

이 스킬의 파일

  • assets/voxel-kit.js: 키트(텍스처, 재질, 앱 루프, 궤도 카메라, 낮/밤 하늘, 섬 지형, 스튜디오 플랫폼, 캐릭터 릭, 파티클, 팝인, 폭발, 횃불, 라우팅 헬퍼, 레코더, 캡처 모드). 장면을 작성하기 전에 반드시 읽으세요: 아래 API 참조는 요약이며, 파일이 진실입니다.
  • assets/template.html: 키트 마커, 섬, 캐릭터 및 작은 타임라인이 있는 시작 페이지.
  • examples/house-builder.html: 건축가가 집을 블록 하나씩 짓고, 환호하고, 폭발하고, 반복합니다.
  • examples/melting-crystal.html: 물리 예제(6×6×6 얼음 격자의 Lindemann 용융, 복셀 온도계, 웅덩이, 재결빙). 과학 설명을 위해 이 구조를 복사하세요.
  • scripts/inline_kit.py: 페이지의 <!-- VOXEL_KIT -->를 키트로 대체하여 하나의 파일로 만듭니다.
  • scripts/render.py: PNG 프레임 및 .mov / .mp4 / .webm으로 프레임 정확한 렌더링.

이 SKILL.md만 사용 가능하고 폴더가 없는 경우, 빌드 전에 https://github.com/normix93/voxel-animations 에서 전체 스킬을 받으세요.

워크플로

  1. 아이디어를 한 줄로 정리: 무엇을 만들고, 변환하거나 설명하며, 루프가 어떻게 끝나는지(리셋, 폭발, 정지, 카메라 비행 아웃) 결정합니다. 대화형 페이지, 편집용 비디오(투명 배경 여부), 세로 숏(1080×1920) 등 목적지를 결정합니다.
  2. 타임라인으로 스토리보드 작성: 3~6개의 비트와 지속 시간(예: 0–2초 빈 부지 → 2–40초 건설 → 40–44초 환호 → 44–49초 폭발 → 반복). 각 비트는 하나의 app.onUpdate 상태 머신에서 mode입니다(집 예제 참조).
  3. assets/template.html에서 시작하여 키트 마커를 유지하고 SCENE 섹션을 작성합니다. 키트 조각을 재사용하고 다시 작성하지 마세요. 모든 것을 한 페이지에 유지합니다.
  4. 페이지 빌드: python3 scripts/inline_kit.py scene.src.html scene.html.
  5. 확인: 페이지를 열거나(또는 render.py로 몇 프레임을 폴더에 렌더링하고 확인)합니다. 블록이 떠 있거나 겹치는지, 캐릭터가 벽을 통과하는지, 카메라가 나무에 걸리는지, 처음 몇 초가 비어 있는지, 투명 블록이 깜빡이는지 확인합니다.
  6. 전달: 환경이 지원할 때 페이지를 아티팩트로 게시하고 .html 파일도 함께 제공합니다. 요청 시 비디오를 렌더링합니다(내보내기 참조).

스타일 규칙

  • 독창성만. 기존 게임의 텍스처, 사운드, 로고, 몹, 캐릭터 또는 이름을 절대 사용하지 마세요. 출력물을 "Minecraft"라고 부르지 마세요: 복셀, 블록, 블록 월드라고 말하세요. 키트의 절차적 텍스처와 안전모 건축가는 안전하게 사용 및 수정할 수 있습니다.
  • 픽셀 선명도: NearestFilter가 있는 16×16 텍스처(키트가 처리). 강한 조명, 선명한 그림자, 재질당 적은 색상, 작은 노이즈.
  • 움직임에 무게감: 블록은 오버슈트(app.pop)로 팝인, 잔해는 중력(≈20–22 blocks/s²)과 감쇠 바운스 사용, 캐릭터는 ~5 blocks/s로 걷고 부드럽게 회전합니다. 물리적 동작에 선형 트윈을 피하세요.
  • 한눈에 읽기 쉬움: 중앙에 하나의 주요 주제, 카메라는 천천히 궤도 회전(autoSpeed 0.05–0.1), 배경은 차분함(하늘 또는 studio 색상).
  • 텍스트: 페이지에는 제목과 상태 줄이 있을 수 있습니다. 비디오의 경우 ?clean(UI 없음)으로 렌더링합니다. 비디오에 레이블이 필요한 경우 매우 짧은 단어를 사용하고, 설명은 내레이션이나 페이지에 속하며 프레임에 있으면 안 됩니다.

키트 API (요약)

const app = VK.createApp({
  title, subtitle, hint,            // UI 텍스트 (?clean 또는 키 H로 숨김)
  sky: 'day' | 'night' | 'studio',  // studio = 평평한 색상(studioColor), 안개 없음
  cycle: false, dayLength: 48, tod: .27,  // 시간 0..1 (.25 일출 쪽, .75 밤)
  camera: { radius, phi, theta, target: [x,y,z], auto: true, autoSpeed: .07 },
  speed: 1, seed: 7, fileName: 'my-scene', shadowSize: 28,
});
app.M.grass | dirt | stone | sand | planks | roof | log | leaves | glass | water | ice | snow | cobble | brick | lava
VK.solid(0xff8800, { glow, opacity, noise, border })  // 색상 픽셀 블록 재질
VK.block(app, 'planks' | material, x, y, z, { pop: true })   // 단일 메시 (이동/팝)
VK.instanced(app.scene, material, [[x,y,z], ...])             // 정적 블록, 한 번의 드로우 콜
const world = VK.island(app, { seed, radius: 18, flatRadius: 7.5, trees: 10, water: -1, snowLine })
  // → world.groundTopAt(x, z), world.hAt(ix, iz)
VK.platform(app, { size: 16, top: .5, mat: 'stone', topMat: 'cobble' })  // 스튜디오 바닥
const hero = VK.character(app, { ground: world.groundTopAt, position: [x,0,z], yaw, colors: { shirt:[r,g,b], hat: 0xf5c518 | null, ... } })
  hero.goTo([[x,z], ...]) · hero.arrived · hero.face(x, z, dt) · hero.jump(v)
  hero.pose = 'idle' | 'reach' (set hero.reach 0..1) | 'cheer' | 'panic' | 'wave'
  hero.lookTarget = {x,y,z} | null
VK.standOutside(x, z, { halfX, halfZ, cx, cz })   // 상자 블록 작업을 위해 서 있을 위치
VK.routeAround(from, to, { halfX, halfZ, cx, cz }) // 상자 주위를 걷는 경유지
VK.explode(app, meshes, { center, power, ground, onDone })
VK.torch(app, x, y, z)                               // 밤에 불빛이 강해짐
app.puff(position, material, n, power) · app.pop(mesh) · app.clearParticles()
app.onUpdate((dt, time) => { ... })  // dt는 이미 speed에 따라 스케일링됨; 캡처 모드에서 결정적
app.rand()                           // 시드 기반 난수: Math.random 대신 사용
app.status(html) · app.button({ label, key, toggle, on, onClick }) · app.standardButtons({ cycle })
app.start()

장면을 올바르게 유지하는 규칙:

  • app.rand()(시드 기반)를 사용하고 Math.random()은 절대 사용하지 마세요. 그래야 렌더링이 반복 가능합니다.
  • 모든 움직임을 dt를 사용하는 app.onUpdate에 넣고, 애니메이션에 setTimeout/setInterval을 절대 사용하지 마세요(캡처 모드가 깨집니다).
  • 블록은 1×1×1이며 정수 좌표에 중심이 있습니다. 높이 h인 기둥의 상단 표면은 h + 0.5에 있습니다. 캐릭터는 groundTopAt(x, z)에 섭니다.
  • 정적 배경 → VK.instanced; 움직이거나, 팝하거나 폭발하는 모든 것 → VK.block.
  • 대량 카운트: 움직이는 메시를 약 1500개 미만으로 유지; 그 이상은 InstancedMesh로 애니메이션 처리합니다.

레시피

  • 빌드 시퀀스: 순서가 있는 계획 [{type,x,y,z}](층별로, 둘레를 따라 걷기; 지붕은 지그재그 줄)를 만듭니다. 각 항목에 대해: standOutside로 경로 지정, pose='reach' 설정, 리치의 약 45%에서 스폰, 다음. examples/house-builder.html 참조.
  • 블록으로 물리 설명: 수량을 보이는 것으로 매핑합니다. 온도 → 떨림 진폭 ∝ √T (등분배); 압력 → 블록 충돌; 에너지 레벨 → 탑의 층; 장 → 블록 화살표; 엔트로피 → 순서화된 벽 재섞기; 중력 → 지지되지 않을 때 넘어지는 더미. 화면의 숫자 대신 복셀 게이지(melting-crystal.html의 온도계)로 제어 변수를 보여줍니다.
  • 변환: mesh.material 변경(물 ↔ 얼음, 돌 → 용암), scale.y로 평평하게, 두 위치 사이의 이징 lerp로 슬라이드.
  • 원자 / 분자: 입자용 VK.solid(색상) 큐브, 전자나 광자용 glow: true, 작은 큐브(mesh.scale.setScalar(.3))는 궤적용.
  • 반복되는 엔딩: 폭발(VK.explode) → 리셋, 또는 정지 + 느린 카메라, 또는 횃불과 함께 밤이 내림(app.sky.cycle = true).

내보내기

URL 매개변수(키트로 빌드된 모든 페이지에서 작동): ?clean UI 숨김 · ?alpha 투명 배경(하늘, 안개 없음) · ?seed=3 · ?speed=2 · ?night · ?capture&fps=30 렌더러가 사용하는 프레임 정확 모드.

키: H UI 숨김 · Space 일시 정지 · V 빠른 실시간 WebM 녹화(로컬 파일에서 페이지를 열 때 작동; 호스팅된 미리보기는 다운로드를 차단할 수 있음).

프레임 정확 비디오(편집에 선호):

pip install playwright && python3 -m playwright install chromium   # 한 번만, ffmpeg도 필요
python3 scripts/render.py scene.html --seconds 12 --fps 30 --out scene.mov             # ProRes 422 HQ
python3 scripts/render.py scene.html --seconds 12 --alpha --out overlay.mov            # 알파 포함 ProRes 4444
python3 scripts/render.py scene.html --size 1080x1920 --warmup 3 --out short.mp4       # 세로 H.264
python3 scripts/render.py scene.html --seconds 5 --out frames/                         # PNG 프레임만

--warmup은 녹화 전 장면 초를 건너뜁니다; --params "seed=3&night"는 URL 매개변수를 추가합니다; --headed는 보이는 브라우저를 사용합니다(실제 GPU, 대부분의 노트북에서 더 빠름). --alpha를 사용하면 카메라는 계속 궤도 회전합니다; 정적 오버레이를 위해 camera: { auto: false }로 설정하세요.

전달 전 확인

  • 페이지가 콘솔 오류 없이 열리고, 첫 프레임에 이미 주제가 보입니다.
  • 루프가 최소 두 번 작동합니다(리셋이 메시, 조명 및 파티클을 지웁니다).
  • 캐릭터가 절대 벽을 통과하지 않으며, 의도하지 않은 한 아무것도 떠 있지 않습니다.
  • 비디오의 경우: ?clean으로 렌더링, 올바른 크기/fps, 요청 시 알파 채널이 확인되었는지 확인.
  • 코드, 제목, 파일 이름 어디에도 타사 게임 이름, 텍스처 또는 캐릭터가 없습니다.

관련 스킬