픽셀 단편 영화 (Remotion + three.js + 픽셀 스프라이트)
부드러운 3D 세계, 픽셀 아트 사람들. 모든 것(사람, 건물, 텍스처, 음악, 음향 효과)이 코드로 그려지거나 합성되므로 결과물은 독창적이며 별도의 에셋이나 라이선스가 필요하지 않습니다. 이 템플릿은 완전하고 작동 가능한 스타터이며, 이 파일만 있으면 됩니다.
시작
새 프로젝트 (template/ 복사, 설치, 음악 및 사운드 생성, 타입 체크):
~/.claude/skills/pixel-film/bin/new-film.sh <폴더>
cd <폴더> && npm run studio # 컴포지션: Film (36초 스타터) 및 CharSheet (모든 사람과 포즈)
기존 Remotion 프로젝트에 추가하는 경우: template/src/film/, template/src/components/ui.tsx, template/src/theme.ts, template/scripts/ 및 template/public/fonts/를 복사하고 template/package.json의 의존성(three, @remotion/three, @react-three/fiber, @types/three, @remotion/bundler, @remotion/renderer; 모든 Remotion 패키지는 정확히 동일한 버전)을 추가하세요.
빌드 전에 합의할 사항
작업을 변경하는 경우에만 질문하고, 그렇지 않으면 선택하고 선택한 내용을 말하세요.
- 포맷. 16:9 (1920×1080)는 거리, 추적 샷, YouTube 및 Facebook 피드에 적합합니다. 9:16 (1080×1920)은 Reels/TikTok/Shorts에 적합하지만 프레임이 좁아(수평 시야의 약 절반) 와이드 샷과 어깨 너머 샷을 다시 생각해야 합니다. 불확실할 때 질문하세요: 모든 샷이 변경됩니다.
- 스토리 및 길이. 2초 단위(30fps에서 60프레임)로 시작 시간이 있는 장면 표로 작성하세요: 무슨 일이 일어나는지, 누가 무슨 말을 하는지, 시간대, 카메라. 45–80초는 광고나 단편에 적합합니다.
- 언어. 타이틀 카드와 자막은 대상 언어로 표시합니다.
- 강조할 내용 (제품 또는 앱의 경우): 기능이 드러나는 명확한 순간 하나를 음악의 드롭 부분에 배치하고 실제 제품을 사용합니다("실제 앱 보여주기" 참조).
구성 요소 (template/src)
| 파일 | 설명 | 사용자 지정 |
|---|---|---|
film/people.ts | 픽셀 사람, 64×112, 캔버스 모양으로 그린 다음 픽셀 아트로 변환(색상이 팔레트에 스냅됨, 빛 반대쪽 면에 셀 셰이딩, 부품 사이에 더 어두운 선, 외곽선). 뷰: 전면, 측면(걷기 사이클 walk0–3), 후면. 포즈: idle blink talk happy wave think worried phone pay, sideIdle sideTalk, back backPhone, sitPhone sitHappy. 샘플 캐스트: owner kid uncle woman grandma man. | PEOPLE: 피부, 머리카락 및 hairStyle (번, 짧은, 포니, 대머리, 모자), 상의/하의/신발 색상, topDots, dress, apron, sleeveless, glasses, mustache, belly, kid, iris. CharSheet에서 확인하세요. 새로운 의상, 소품 또는 헤어스타일은 drawPerson, face, hairFront에 추가합니다. |
film/Street3D.tsx | 세트. 중앙에 상점: 내부(상품 선반, 카운터, 전구, 냉동고, 의자), 전면(카운터 위의 넓은 개구부, 선택적 와이어 그릴 및 행잉 스트립, 간판, 카운터 보드, 차양). 이웃(유리 앞 상점, 줄무늬 차양이 있는 셔터 닫힌 상점, 주택), 야간에 조명이 켜진 발코니와 자루시 창문이 있는 2층, 인도, 도로, 램프와 선택적 처진 전선이 있는 기둥, 나무, 화분, 테이블과 의자. time에 따른 조명(0 아침, 1 정오, 2 골든 아워, 3 황혼, 4 밤; 분수 혼합)은 그림자, 하늘, 별, 안개 및 램프 글로우를 포함합니다. 사람들은 그림자를 드리우는 조명이 켜진 광고판입니다. 선택적 items (카운터 위의 제품), cat, fx.beam / fx.scanX (카운터를 스캔하는 전화기). | SET 상단: 간판 문구 및 색상, 벽 색상, 카운터 보드, 그릴, 행잉 스트립, 제품 (public/products/<name>.png), 이웃 이름 및 색상, 상층, 전선. 좌표: 상점 전면 z = 1.2 (개구부 x −2..2, y 1..2.3, 카운터 상단 y = 1.0), 카운터 뒤 사람 [0, 0, 0.25], 전면 고객 [0.7, 0.12, 1.95]; 인도 상단 y = 0.12 (z 1.2 ~ 3.6), 그 너머 도로; 건물 x = −19 ~ 19. 다른 종류의 장소(카페, 사무실, 시장)의 경우 JSX에서 상점 조각을 변경하세요: 일반 상자, 평면 및 캔버스 텍스처입니다. |
film/kit.tsx | camMove (이지드 카메라 키프레임 + 핸드헬드 드리프트), who (경로 위의 사람: 가는 방향을 향해 측면 보기로 걷기, 그렇지 않으면 예약된 포즈; 멈춤 상태에서 깜빡임), headAt (머리 위 화면 지점), Line (화자 색상이 있는 자막), Card (큰 캡션 또는 시간 카드), Sfx, steps (발소리), PhoneIn (앱 화면이 있는 전화기), Dim, Fade, num. | SPEAKER_COLORS; 어린이 머리 높이를 위한 HEAD. |
film/Look.tsx | FilmLook: 태양 쪽에서 오는 태양 광선, 시간대별 색상 그레이딩, 비네트, 그레인, 레터박스 바. | 동일한 time으로 모든 3D 장면 위에 배치하세요. |
film/overlay.tsx, film/pixel.ts | 머리 위 픽셀 아이콘 (bulb sweat heart question coin wifiOff clock zzz) 및 FoundBox (찾은 항목 주위 상자와 카운팅 % 레이블). | 아이콘은 pixel.ts의 작은 문자 그리드입니다. |
components/ui.tsx | Phone: 1080×1920 스크린샷을 표시하는 전화기 프레임, 줌 키프레임(cams), 탭 및 와이프 포함. | — |
film/Film.tsx | 스타터: 타이틀과 트래킹 워크가 있는 아침 크레인; 골든 아워 투샷 대화; 밤, 모두가 손을 흔들고, 뒤로 당기고 위로 올라가며, 엔드 카드. | 스토리로 교체하세요. |
scripts/make-music.mjs + music-plan.json | 계획에 따라 배치된 독창적인 경쾌한 트랙(120 BPM, C–G–Am–F; 마림바, 패드, 베이스, 리드 후크, 라이저, 최종 히트) + 영화 같은 사운드(whoosh, pop, tap, tick, beep, chaching, chime, shutter, scan, detect, check, sparkle, impact, printer, stamp, page, womp). | 계획(초 단위): sections (인트로 / 메인 / 브레이크 / 엔드), lead 및 up 범위, hits (드롭), final (종료 4초 전). |
scripts/make-sfx.mjs | public/audio/8bit/의 8비트 사운드(talk, coin, idea, cash, step, jump, select, done, scan, detect, womp, pop, tap, whoosh) 및 선택적 칩튠 트랙. | — |
scripts/capture-screens.mjs | 웹 앱의 실제 화면을 전화기 스크린샷으로 캡처합니다 (아래 참조). | scripts/shots.json |
scripts/stills.mjs, scripts/audio-check.mjs | 긴 렌더링 전에 프레임과 음악을 확인합니다. | — |
카메라 문법 (영화처럼 보이게 하는 요소)
- 오프닝 크레인: 거리 위를 높고 넓게, 거리 높이로 내려옵니다 (
[-5, 7.5, 21] → [-1.5, 2.6, 13.5], fov 34). - 트래킹: 도로 쪽에서 걷는 사람을 따라갑니다: 카메라 x = 사람 x + 0.9, z ≈ 7.4, y ≈ 1.35, 사람을 바라봄, fov 30.
- 투샷 상점 앞에서 고객 뒤가 아닌 고객 쪽에서 촬영 (카메라 x ≈ −0.9, 고객이 x 0.7에 서 있을 때), 그렇지 않으면 고객 스프라이트가 다른 사람을 가립니다.
- 클로즈업: 카운터 높이 위에 카메라를 두고 (y ≈ 2.1, y ≈ 1.36을 바라봄) 느린 푸시인 (fov 24–28), 그래야 카운터 위 물건이 얼굴을 가리지 않습니다.
- 어깨 너머 내부에서,
backPhone포즈의 누군가 뒤에서: 그들은 프레임 아래쪽에, 카운터와 밖의 고객이 보입니다. - 일렬로 선 사람들: 옆으로 트럭 이동.
- 엔딩: 모두가 카메라 가까이에서 손을 흔든 다음, 거리 전체 위로 뒤로 당기고 위로 올라갑니다 (
[0, 1.6, 7.6] → [0, 10.5, 27],[0, 3.6, 0]을 바라봄), 그 위에 엔드 카드, 그리고 페이드 투 블랙. - 시간 카드 (아침, 정오, 골든 아워, 밤…)는 빛이 변할 때 상단에; 대화 자막은 하단에 (영화 크기에서는 말풍선보다 읽기 좋습니다).
- 장면은 마디선 (60프레임의 배수)에서 시작하고 드롭이 핵심 순간에, 최종 히트가 엔드 카드에 오도록 음악 계획을 설정하세요.
실제 앱 보여주기
모형이 아닌 실제 제품을 보여주세요. 웹 앱(또는 모바일 앱의 웹 빌드)의 경우: 가짜 데이터를 시드한 다음 node scripts/capture-screens.mjs scripts/shots.json을 실행하세요 (npm i -D playwright && npx playwright install chromium 필요). 1080×1920 전화기 화면을 public/shots/로 촬영합니다. "camera"에 JPEG를 제공하면 앱의 카메라가 해당 이미지를 보므로 스캔 또는 인식 기능이 실제로 실행됩니다; 실제 브랜드 대신 가짜 제품(SVG → sharp 또는 캔버스로 JPEG)으로 그 장면을 그리세요. 화면을 PhoneIn / Phone에 tap/select 사운드에 맞춘 탭과 함께 배치하세요. 영화에 표시되는 숫자(가격, 일치율 %)는 앱이 실제로 생성한 것이어야 합니다.
확인 후 렌더링
npm run stills -- 100 400 900 …→out/stills/*.jpeg절반 크기. 모든 장면의 프레임을 확인하세요: 사람들이 서로를 가리는지, 얼굴이 가려지는지, 텍스트가 간판 위에 있는지, 낮처럼 보이는 밤인지, 자막이 복잡한 영역 위에 있는지. 렌더링하기 전에 수정하세요; 전체 렌더링은 느립니다.node scripts/audio-check.mjs: 250Hz 미만은 ~65% 미만, 250–2000Hz는 30% 이상이어야 합니다. 그렇지 않으면 음악이 전화기와 노트북 스피커에서 아무것도 아닌 것처럼 들립니다.npm run render(--gl=swangle: CPU의 WebGL). 그림자 포함 1080p에서 초당 프레임을 예상하세요 (80초 영화 ≈ 소형 서버에서 2시간); 백그라운드에서 실행하세요. 또는 사용자가 GPU가 있는 브라우저의 스튜디오에서 렌더링합니다.
함정
- 세로는 좁습니다: 카메라 축에서 1m 떨어진 사람이 2m 거리에 있으면 프레임 밖입니다. 9:16에서는 피사체를 수직으로 분리하세요 (카메라 높게, 가까운 사람 프레임 아래쪽).
- 스프라이트가 카메라를 막습니다: 카메라와 피사체 사이의 사람이 프레임을 가득 채웁니다 (크고 평평한 평면입니다). 사람뿐만 아니라 카메라도 움직이세요.
- 베이스가 강한 음악은 작은 스피커에서 침묵처럼 들립니다: 베이스에 배음을 주고, 코드와 멜로디를 중음역에 유지하며, 강한 로우패스를 하지 마세요.
- 밤이 너무 밝습니다: 앰비언트와 하늘 빛을 낮게 유지하고 램프, 간판 및 조명이 켜진 창문이 장면을 비추게 하세요 (프리셋이 그렇게 합니다).
- 텍스처: 비동기 로드를
delayRender/continueRender로 감싸고 존재하지 않는 파일을 요청하지 마세요 (렌더링이 중단됩니다). - 결정론: 프레임이나 생성된 오디오에
Math.random을 사용하지 마세요 (시드 랜덤 또는 Remotion의random(seed)사용), 그래야 재렌더링이 일치합니다. - 글꼴은
public/fonts에 포함되어 제공됩니다 (Poppins, Caveat, Press Start 2P; SIL 오픈 폰트 라이선스), 따라서 렌더링에 인터넷이 필요하지 않습니다. - Remotion 자체 ffmpeg (
node_modules/@remotion/compositor-*/ffmpeg)에는 필터가 거의 없습니다: 분석을 위해 PCM WAV로 디코딩하고, libmp3lame으로 MP3 인코딩하며,-ss로 프레임을 가져옵니다.
규칙
- 독창적인 캐릭터, 장소 및 제품만 사용: 실제 브랜드, 로고 또는 사람은 사용하지 않으며, 특정 기존 게임, 영화 또는 프로그램(캐릭터, 아트 또는 외관)을 이름을 바꾸더라도 재현하지 마세요.
- 광고의 주장은 제품에 대해 사실이어야 합니다. 사용자가 게시하기 전에 확인해야 할 사항을 지적하세요 (예: "앱 스토어에서 무료"는 공개된 후에만).