실제적인 3D 단편 영상 (Blender + Python)
모든 프레임은 Claude가 Python으로 빌드한 장면을 실제 Blender로 렌더링한 것입니다. AI 이미지나 비디오 모델을 사용하지 않습니다.
최종 출력: 1080x1920, 30fps, H.264, 최대 30Mbps. 경로: <skill> = 이 폴더입니다. 에피소드는
<project>/blender-shorts/<slug>/에 저장되고, 다운로드한 애셋은 <project>/blender-shorts/assets/에, 채널 설정은
<project>/blender-shorts/brand.json에 저장됩니다. 스크립트는 python <skill>/scripts/<name>.py로 실행합니다.
먼저 읽을 것: references/style.md (규칙), references/traps.md (수정 사항을 만들기 전에).
설정 (PC당 한 번)
- Blender 5.x (Program Files에서 자동으로 찾고, 없으면
BLENDER=<blender.exe 경로>설정). python -m pip install numpy opencv-python-headless pillow; ffmpeg를 PATH에 추가.- 파이프라인이 작동하는지 확인:
examples/test-cell/을blender-shorts/test-cell/로 복사한 후, build, still, frames, finish 단계를 실행. RTX 3080 Laptop에서 EEVEE로 90프레임 1080x1920을 약 2분에 렌더링합니다.
0단계: 시작 질문 (항상, 작업 전에)
AskUserQuestion 도구를 사용하여 최대 4개의 질문씩 두 라운드로 묻고, 세 번째 라운드는 음성 답변에 따라 달라집니다. blender-shorts/brand.json이 있으면 먼저 한 가지 질문을 합니다: "지난번과 같은 설정으로 할까요?" (한 줄로 요약해서 보여줌) "예" / "일부 변경" 옵션. "예"면 세 번째 라운드의 주제별 부분으로 건너뜁니다.
권장 옵션을 먼저 제시. 모든 답변을 brand.json(채널 전체)과 에피소드의 episode.json에 저장합니다.
라운드 1: 주제와 음성 방식
- 주제: "3가지 제안해 줄래요?" / "직접 고를게요" (다른 항목 아래에 직접 입력). 추천: 신체 또는 작동 원리에 대한 질문으로, 그림으로 설명할 수 있고 YouTube에서 각도의 독창성을 확인한 것.
- 음성:
- ElevenLabs 음성 (권장): 기본 음성, 정확한 단어 타이밍으로 스크립트에서 생성.
- 내 목소리 클론 (ElevenLabs): 1-3분 분량의 깨끗한 음성을 한 번 업로드하면 모든 에피소드가 해당 목소리로 말합니다. 오직 자신의 목소리이거나 서면 동의를 받은 목소리만 가능.
- 직접 녹음할게요: 사용자가 스크립트를 녹음하면 Claude가 정리하고 단어 타이밍을 찾아 장면을 구성합니다.
- 음성 없음, 자막만: 스크립트는 2.8단어/초로 타이밍이 정해지고 자막이 영상에 포함되며,
captions.srt파일을 제공하여 사용자가 편집기에서 정확한 타이밍에 음성을 추가할 수 있습니다.
- 길이: 30초 (처음에는 권장) / 45초 / 60초. 2.8단어/초 기준 약 80 / 120 / 165단어.
- 레퍼런스 영상: "아니요, 내장된 스타일 규칙을 사용할게요" (권장) / "네, 파일이나 링크를 줄게요" (
measure.py로 측정, 개인 학습용).
라운드 2: 룩
- 룩: 스튜디오 배경 (권장: 하나의 시그니처 색상이 모든 것을 배경으로, 장르의 특성) / 실제 사진 배경판 (경기장, 거리, 3D 뒤 배경) / 혼합 (배경판과 실제 장소를 "어디" 비트에 사용).
- 배경색 (배경 사용 안 하면 건너뜀): 피치
#F2D7C9(지금까지 사용한 색) / 민트#CFE8DF/ 진한 네이비#1F2A44/ 사용자 지정 (hex). 레퍼런스 채널의 색상은 절대 사용하지 않음. - 메인 캐릭터: "메인 캐릭터가 있나요?" (
references/characters.md)- 리깅된 캐릭터를 직접 제공할게요: .blend / .fbx / .glb 파일 (Mixamo, Character Creator, 스토어).
- 하나 만들어 주세요 (캐릭터가 없을 경우 권장): MPFB로 Blender에서 제작, 계정 불필요, 셔츠에 우리 로고.
- 무료 리깅된 캐릭터를 다운로드할게요: Claude가 2-3개 후보를 제안 (출처, 라이선스, 외형). 계정이 필요한 사이트(Mixamo, Renderpeople, Sketchfab)는 사용자가 다운로드하고 경로를 제공.
- 캐릭터 없음: 물체, 신체 부위 및 장소만.
메인 캐릭터가 존재하게 되면 (
assets/host/host.blend), 이 질문은 "<이름>을 다시 사용할까요?"로 바뀝니다.
- 렌더 엔진:
- 자동 (권장): EEVEE 빠름을 모든 곳에, Cycles 빠름은 피부 클로즈업, 구름, 유리, 머리카락에서 판정에 실패한 장면에만 사용.
- EEVEE 빠름만: 가장 빠름, 약 1초/프레임.
- Cycles 빠름만: 약 2배 느리지만 더 부드럽고 자연스러운 조명.
- 고품질:
high프리셋, 빠름보다 약 2-3배 느림.
라운드 3: 음성 답변에 따라 다름
- ElevenLabs 또는 클론: 중요. 프로젝트 또는 상위 폴더의
.env파일에ELEVENLABS_API_KEY=가 있는지 확인 (절대 출력하지 않음). 있으면 "ElevenLabs 키를 찾았습니다"라고 말하고 묻지 않음. 없으면 물음: "키를 추가해 주세요: 여기에 붙여넣으면.env에 저장하거나, 직접.env에ELEVENLABS_API_KEY=...줄을 추가하세요 (채팅 외부에 보관됨)". 붙여넣은 키는<project>/.env에만 저장하고, 절대 출력하지 않으며 다른 파일, 커밋, 로그에 넣지 않음. - ElevenLabs: 음성: 차분한 나레이터 (
sound.py의 기본 id) / "내 ElevenLabs 라이브러리에서 선택" (GET /v1/voices로 목록, 이름만 표시) / 음성 ID (직접 입력). 음성 모델: eleven_multilingual_v2 (권장: 안정적, 최고의 단어 타이밍) / eleven_v3 (더 표현력 풍부, 예측 어려움). - 클론: 샘플 파일 경로를 묻고
sound.py <ep> clone <files> --name "<이름> 목소리"실행; 음성 ID가 저장되어 이후 모든 에피소드에서 재사용. - 직접 녹음: 스크립트 승인을 기다린 후, 조용한 방에서 한 번에 녹음(팔 길이로 든 전화기)하고 파일 경로를 제공하라고 안내. (승인된 스크립트에 녹음하는 것이 영상과 음성을 동기화하는 방법)
- 메인 캐릭터, 라운드 2 답변에 따라:
- 제공: 파일 경로 (텍스처 폴더가 별도면 함께) 요청.
- 만들기: 나이, 체형, 헤어 및 의상 스타일(간단한 단어)을 묻고 MPFB 설치 요청.
- 다운로드: 2-3개 후보를 옵션으로 제시 (이름, 외형, 라이선스, 계정 필요 여부)하고 선택하도록 함.
- 모든 음성 옵션: 자막 포함? 예 / 아니요 (음성 없는 경우 항상 자막 포함).
- 모든 옵션: 배경 음악: 없음, 효과음과 룸톤만 (처음에는 권장) / 내 트랙 (파일 경로, 사용자가 권리를 확인) / YouTube Audio Library 트랙 (사용자가 다운로드하여 경로 제공).
다른 것은 묻지 않음; 아래 모든 항목은 기본값이 있습니다. "특정 모델" 질문: 이 파이프라인에는 AI 이미지나 비디오 모델이 없습니다. 그와 유사한 선택지는 렌더 엔진(라운드 2), ElevenLabs 음성 모델(라운드 3), 그리고 이 스킬을 실행하는 Claude 모델(Opus, high effort)입니다.
엔진 프리셋 (사용자가 선택한 설정, 유지)
- EEVEE 빠름 (기본,
b3d.EEVEE_PRESETS['fast']): 16 샘플, 절반 해상도 레이트레이싱 및 GI, 1 섀도우 레이. ~0.9-1.2초/프레임(1080p, 3080 기준),high와 99-99.9% 유사. - Cycles 빠름 (
b3d.CYCLES_PRESETS['fast']): 32 샘플, 1초 시간 제한, OptiX 디노이저, 2-3 바운스, 빠른 GI 근사, 영구 데이터. ~1.7초/프레임. 클로즈업에서 디노이저 번짐이 나타나면 해당 장면에 2초 시간 제한 적용. - 렌더링 시
--quality draft | fast | high, 재빌드 불필요. 장면별 엔진:setup_render(engine=...)또는 재빌드 없이 A/B 비교를 위해B3D_ENGINE=CYCLES python render.py <ep> build. 배경과 그레이딩이 일치한다면 한 단편에서 엔진 혼용 가능 (각 장면을 자체 .blend에서 프레임 범위 렌더링).
파이프라인 (각 단계 후 저장; 텍스트 덩어리 대신 스틸 이미지 보여주기)
- 주제 및 사실. 모든 숫자를 찾아 출처와 함께
episode.json의science에 기록. 불확실한 유명 숫자는 "과학자들은 추정합니다"라고 표기. 대형 채널과 동일한 주제도 가능, 그들의 단어는 사용하지 않음. - 레퍼런스 측정 (라운드 1에서 '예'라고 답한 경우만):
measure.py <folder> --out <ep>/reference.json. 그렇지 않으면 style.md의 기본값 사용. - 스크립트
episode.json(examples/episode.template.json참조): 2인칭, ~2.8단어/초, 선택한 길이, style.md의 비트 구조. 보여주고 승인 대기. 승인 후 "바로 진행"하여 스틸 이미지까지. - 음성 및 타이밍, 라운드 1 답변에 따라:
- ElevenLabs / 클론:
sound.py <ep> voice->audio/voice.wav,words.json,captions.srt. - 직접 녹음: 사용자 파일을 기다린 후
sound.py <ep> own <file>(단어 시간: faster-whisper 설치 시 사용, 키가 있으면 ElevenLabs STT, 아니면 무음 구간에서 추정; 추정이 부정확하면pip install faster-whisper제안). - 음성 없음:
sound.py <ep> captions->words.json+captions.srt,"wps"(2.8) 값 사용. 그런 다음shots.md작성: 비트별로 프레임 범위(단어 시간 기반), 카메라 움직임(달리 인/홀드+크립/풀 아웃/플라이스루), 각 홀드 동안 움직이는 요소. 약 7개 전환당 최대 1개의 하드 컷.
- ElevenLabs / 클론:
- 먼저 9초 테스트. 전체 단편보다 먼저 한 비트를 전체 파이프라인으로 진행:
scene.py(b3d 헬퍼 사용). 렌더, finish,measure.py, 레퍼런스가 있으면compare.py reference.json ours.json. 차이가 바로 작업 목록입니다. 카메라를 수정하여 저크와 측면 드리프트가 일치할 때까지(단일 축, eased 키). - 월드 및 캐릭터. 먼저 캐릭터,
references/characters.md의 경로를 통해 항상b3d.import_character(path, height=1.75)사용: 실제 키로 스케일링하고 바닥에 발 위치, 불필요한 카메라와 조명 제거, 가중치 파트를 리그에 바인딩하고 보고서 출력(리그 유형, 리그를 따르지 않는 파트, 얼굴 쉐이프 x/52, 누락된 텍스처). 보고서의 모든 항목을 수정한 후 회전 스틸 이미지를 만들고assets/host/host.blend저장. 월드는references/assets.md참조 (다운로드 목록, 출처 + 라이선스 + 크기, 한 번 요청). 규칙: 실제가 존재하면 다운로드하고 절대 모델링하지 않음. - 스틸 이미지 및 심사.
render.py <ep> still <frames...> --pct 50(각 비트에 대해). 그런 다음 별도 에이전트(Agent 도구)를 스틸 이미지와references/realism.md와 함께 실행; 10점 만점으로 점수를 매기고 가장 나쁜 세 가지 가짜 요소를 지적. 수정, 재렌더링, 재심사. 8.5점 이상에서만 렌더링 진행. 사용자에게 스틸 이미지와 점수 표시. "자동" 엔진에서 EEVEE 단축키로 실패한 장면은 여기서 Cycles 빠름으로 전환. - 렌더링. 사용자의 터미널 패널(run_in_terminal)에서
render.py <ep> frames실행하여 라이브 진행 막대(완료 프레임 수, 초/프레임, 예상 시간)를 보여줌;<ep>/progress.json을 읽어 "얼마나 되었나요?"에 답변. 재개 가능. 그런 다음render.py <ep> times; 너무 느리면 가장 느린 프레임에 대해references/render-speed.md의 내용을 적용. - 사운드.
beds(월드별 룸톤)와sfx(각 단어에 해당: "뼈"에 "뼈 부딪힘" 소리)를episode.json에 작성한 후sound.py <ep> sfx(키 필요; 없으면 효과 생략 또는 사용자가audio/sfx/<name>.mp3에 제공한 파일 사용) 및sound.py <ep> mix. 믹스 규칙: 음악 +3dB, 효과는 절반, 음성은 변경 없음. - 완료.
finish.py <ep> --audio <ep>/audio/mix.wav [--captions]->out/<slug>-final.mp4. 휴대폰 크기로 시청. 음성 없는 에피소드:captions.srt도 함께 제공하고 해당 타이밍에 음성을 넣어야 한다고 안내. - 보고서: 최종 경로, 심사의 최종 점수, 렌더링 시간(분), ElevenLabs 크레딧(
costs.json), 설명용 크레딧 텍스트(assets.md 라이선스). 레퍼런스 채널이 어떤 도구를 사용한다고 절대 언급하지 않음.
스크립트
| 스크립트 | 실행 환경 | 기능 |
|---|---|---|
b3d.py | Blender | 렌더 설정 + 프리셋 (EEVEE/Cycles, GPU, 룩), 배경 + HDRI, 섀도우 캐처 (Cycles 실물, EEVEE 가짜), 조명, 단일 축 eased 달리 카메라, 재질, import_character (모든 리깅된 .blend/.fbx/.glb, 스케일, 바인드, 보고), parent_to_bone, 쉐이프 키, 컴포지터, 스톱워치 |
render.py | 셸 | build, still, frames (라이브 진행 바, progress.json, 재개 가능), times; --quality |
sound.py | 셸 | voice (ElevenLabs), clone, own (사용자 녹음), captions (음성 없음), sfx, mix; 모든 음성 모드가 captions.srt 작성 |
finish.py | 셸 | 프레임 + 믹스 -> 1080x1920 mp4, 실제 카메라 레이어, --captions 포함 |
measure.py / compare.py | 셸 | 모든 비디오의 프레임별 메트릭; 레퍼런스와 우리 결과 비교 및 할 일 목록 생성 |
scene.py는 blender -b --factory-startup --python scene.py -- <skill>/scripts <ep>/scene.blend로 호출;
examples/test-cell/scene.py에서 시작 (조명 후 shadow_catcher 호출).