Manim 비디오 제작 파이프라인
창작 기준
이것은 교육 영화입니다. 모든 프레임은 가르칩니다. 모든 애니메이션은 구조를 드러냅니다.
코드 한 줄을 작성하기 전에 내러티브 아크를 명확히 하세요. 이 영상이 교정하려는 오해는 무엇인가요? '아하 순간'은 무엇인가요? 시청자를 혼란에서 이해로 이끄는 시각적 이야기는 무엇인가요? 사용자의 프롬프트는 시작점일 뿐입니다 — 교육적 야망을 가지고 해석하세요.
대수보다 기하를 먼저. 공식을 보여주기 전에 형태를 먼저 보여주세요. 시각적 기억은 상징적 기억보다 더 빠르게 인코딩됩니다. 시청자가 공식 전에 기하학적 패턴을 보면, 그 공식은 자연스럽게 느껴집니다.
첫 렌더링 완성도는 타협할 수 없습니다. 출력물은 수정 없이 시각적으로 명확하고 미학적으로 일관되어야 합니다. 무언가 지저분해 보이거나, 타이밍이 안 맞거나, 'AI가 만든 슬라이드'처럼 보이면 잘못된 것입니다.
불투명도 계층화로 주의를 유도하세요. 모든 것을 최대 밝기로 보여주지 마세요. 주요 요소는 1.0, 맥락 요소는 0.4, 구조 요소(축, 그리드)는 0.15로 설정하세요. 뇌는 시각적 현저성을 계층적으로 처리합니다.
숨 쉴 공간. 모든 애니메이션 뒤에는 self.wait()가 필요합니다. 시청자는 방금 나타난 내용을 흡수할 시간이 필요합니다. 절대 한 애니메이션에서 다음 애니메이션으로 서두르지 마세요. 핵심 장면 후 2초의 일시 정지는 결코 낭비가 아닙니다.
일관된 시각적 언어. 모든 장면은 공통 색상 팔레트, 일관된 타이포그래피 크기, 일치하는 애니메이션 속도를 공유해야 합니다. 각 장면마다 무작위로 다른 색상을 사용하는 기술적으로 올바른 비디오는 미학적으로 실패한 것입니다.
사전 요구 사항
scripts/setup.sh를 실행하여 모든 종속성을 확인하세요. 필요: Python 3.10+, Manim Community Edition v0.20+ (pip install manim), LaTeX (Linux에서는 texlive-full, macOS에서는 mactex), ffmpeg. 참조 문서는 Manim CE v0.20.1을 기준으로 테스트되었습니다.
모드
| 모드 | 입력 | 출력 | 참조 |
|---|---|---|---|
| 개념 설명 | 주제/개념 | 기하학적 직관을 포함한 애니메이션 설명 | references/scene-planning.md |
| 수식 유도 | 수학 표현식 | 단계별 애니메이션 증명 | references/equations.md |
| 알고리즘 시각화 | 알고리즘 설명 | 데이터 구조를 포함한 단계별 실행 | references/graphs-and-data.md |
| 데이터 스토리 | 데이터/지표 | 애니메이션 차트, 비교, 카운터 | references/graphs-and-data.md |
| 아키텍처 다이어그램 | 시스템 설명 | 연결과 함께 구성 요소 구축 | references/mobjects.md |
| 논문 설명 | 연구 논문 | 주요 발견 및 방법 애니메이션 | references/scene-planning.md |
| 3D 시각화 | 3D 개념 | 회전하는 표면, 매개변수 곡선, 공간 기하학 | references/camera-and-3d.md |
스택
프로젝트당 단일 Python 스크립트. 브라우저, Node.js, GPU가 필요하지 않습니다.
| 계층 | 도구 | 용도 |
|---|---|---|
| 코어 | Manim Community Edition | 장면 렌더링, 애니메이션 엔진 |
| 수학 | LaTeX (texlive/MiKTeX) | MathTex를 통한 수식 렌더링 |
| 비디오 I/O | ffmpeg | 장면 연결, 형식 변환, 오디오 먹싱 |
| TTS | ElevenLabs / Qwen3-TTS (선택 사항) | 나레이션 음성 |
파이프라인
계획 --> 코딩 --> 렌더링 --> 병합 --> 오디오 (선택) --> 검토
- 계획 — 내러티브 아크, 장면 목록, 시각 요소, 색상 팔레트, 나레이션 대본을 포함한
plan.md작성 - 코딩 — 장면당 하나의 클래스, 각각 독립적으로 렌더링 가능한
script.py작성 - 렌더링 — 드래프트:
manim -ql script.py Scene1 Scene2 ..., 프로덕션:-qh - 병합 — ffmpeg concat으로 장면 클립을
final.mp4로 합치기 - 오디오 (선택 사항) — ffmpeg를 통해 나레이션 및/또는 배경 음악 추가.
references/rendering.md참조 - 검토 — 렌더 미리보기 스틸 샷 생성, 계획과 비교 확인, 조정
프로젝트 구조
project-name/
plan.md # 내러티브 아크, 장면 분석
script.py # 모든 장면이 하나의 파일에 포함
concat.txt # ffmpeg 장면 목록
final.mp4 # 병합된 출력
media/ # Manim에 의해 자동 생성됨
videos/script/480p15/
창작 방향
색상 팔레트
| 팔레트 | 배경 | 주요 | 보조 | 강조 | 사용 사례 |
|---|---|---|---|---|---|
| 클래식 3B1B | #1C1C1C | #58C4DD (파랑) | #83C167 (초록) | #FFFF00 (노랑) | 일반 수학/CS |
| 따뜻한 학술 | #2D2B55 | #FF6B6B | #FFD93D | #6BCB77 | 친근한 느낌 |
| 네온 테크 | #0A0A0A | #00F5FF | #FF00FF | #39FF14 | 시스템, 아키텍처 |
| 모노크롬 | #1A1A2E | #EAEAEA | #888888 | #FFFFFF | 미니멀리스트 |
애니메이션 속도
| 맥락 | run_time | 이후 self.wait() |
|---|---|---|
| 제목/소개 등장 | 1.5초 | 1.0초 |
| 핵심 수식 공개 | 2.0초 | 2.0초 |
| 변환/변형 | 1.5초 | 1.5초 |
| 보조 레이블 | 0.8초 | 0.5초 |
| FadeOut 정리 | 0.5초 | 0.3초 |
| '아하 순간' 공개 | 2.5초 | 3.0초 |
타이포그래피 크기
| 역할 | 글꼴 크기 | 용도 |
|---|---|---|
| 제목 | 48 | 장면 제목, 시작 텍스트 |
| 표제 | 36 | 장면 내 섹션 헤더 |
| 본문 | 30 | 설명 텍스트 |
| 레이블 | 24 | 주석, 축 레이블 |
| 캡션 | 20 | 자막, 작은 글씨 |
글꼴
모든 텍스트에 고정폭 글꼴을 사용하세요. Manim의 Pango 렌더러는 모든 크기에서 비례 글꼴의 커닝을 깨뜨립니다. 전체 권장 사항은 references/visual-design.md를 참조하세요.
MONO = "Menlo" # 파일 상단에 한 번 정의
Text("Fourier Series", font_size=48, font=MONO, weight=BOLD) # 제목
Text("n=1: sin(x)", font_size=20, font=MONO) # 레이블
MathTex(r"\nabla L") # 수학 (LaTeX 사용)
가독성을 위한 최소 font_size=18.
장면별 변주
모든 장면에 동일한 구성을 사용하지 마세요. 각 장면마다:
- 팔레트 내에서 다른 주요 색상 사용
- 다른 레이아웃 — 항상 모든 것을 중앙에 배치하지 마세요
- 다른 애니메이션 진입 방식 — Write, FadeIn, GrowFromCenter, Create 사이에서 다양하게 사용
- 다른 시각적 무게 — 일부 장면은 조밀하게, 다른 장면은 여유 있게
워크플로우
1단계: 계획 (plan.md)
코드 작성 전에 plan.md를 작성하세요. 포괄적인 템플릿은 references/scene-planning.md를 참조하세요.
2단계: 코딩 (script.py)
장면당 하나의 클래스. 모든 장면은 독립적으로 렌더링 가능합니다.
from manim import *
BG = "#1C1C1C"
PRIMARY = "#58C4DD"
SECONDARY = "#83C167"
ACCENT = "#FFFF00"
MONO = "Menlo"
class Scene1_Introduction(Scene):
def construct(self):
self.camera.background_color = BG
title = Text("Why Does This Work?", font_size=48, color=PRIMARY, weight=BOLD, font=MONO)
self.add_subcaption("Why does this work?", duration=2)
self.play(Write(title), run_time=1.5)
self.wait(1.0)
self.play(FadeOut(title), run_time=0.5)
핵심 패턴:
- 모든 애니메이션에 자막 추가:
self.add_subcaption("text", duration=N)또는self.play()에subcaption="text" - 장면 간 일관성을 위해 파일 상단에 공유 색상 상수 정의
- 모든 장면에서
self.camera.background_color설정 - 깔끔한 종료 — 장면 끝에서 모든 mobject FadeOut:
self.play(FadeOut(Group(*self.mobjects)))
3단계: 렌더링
manim -ql script.py Scene1_Introduction Scene2_CoreConcept # 드래프트
manim -qh script.py Scene1_Introduction Scene2_CoreConcept # 프로덕션
4단계: 병합
cat > concat.txt << 'EOF'
file 'media/videos/script/480p15/Scene1_Introduction.mp4'
file 'media/videos/script/480p15/Scene2_CoreConcept.mp4'
EOF
ffmpeg -y -f concat -safe 0 -i concat.txt -c copy final.mp4
5단계: 검토
manim -ql --format=png -s script.py Scene2_CoreConcept # 미리보기 스틸
중요 구현 참고 사항
LaTeX용 Raw 문자열
# 잘못됨: MathTex("\frac{1}{2}")
# 올바름:
MathTex(r"\frac{1}{2}")
가장자리 텍스트의 buff >= 0.5
label.to_edge(DOWN, buff=0.5) # 절대 0.5 미만으로 설정하지 마세요
텍스트 교체 전 FadeOut
self.play(ReplacementTransform(note1, note2)) # note2를 위에 Write(note2)하지 마세요
추가되지 않은 Mobject에 절대 애니메이션 적용 금지
self.play(Create(circle)) # 먼저 추가해야 함
self.play(circle.animate.set_color(RED)) # 그 다음 애니메이션 적용
성능 목표
| 품질 | 해상도 | FPS | 속도 |
|---|---|---|---|
-ql (드래프트) | 854x480 | 15 | 장면당 5-15초 |
-qm (중간) | 1280x720 | 30 | 장면당 15-60초 |
-qh (프로덕션) | 1920x1080 | 60 | 장면당 30-120초 |
항상 -ql로 반복 작업하세요. 최종 출력만 -qh로 렌더링하세요.
참조
| 파일 | 내용 |
|---|---|
references/animations.md | 핵심 애니메이션, 속도 함수, 구성, .animate 구문, 타이밍 패턴 |
references/mobjects.md | 텍스트, 도형, VGroup/Group, 위치 지정, 스타일링, 사용자 정의 mobject |
references/visual-design.md | 12가지 디자인 원칙, 불투명도 계층화, 레이아웃 템플릿, 색상 팔레트 |
references/equations.md | Manim에서의 LaTeX, TransformMatchingTex, 유도 패턴 |
references/graphs-and-data.md | 축, 플로팅, BarChart, 애니메이션 데이터, 알고리즘 시각화 |
references/camera-and-3d.md | MovingCameraScene, ThreeDScene, 3D 표면, 카메라 제어 |
references/scene-planning.md | 내러티브 아크, 레이아웃 템플릿, 장면 전환, 계획 템플릿 |
references/rendering.md | CLI 참조, 품질 사전 설정, ffmpeg, 나레이션 워크플로우, GIF 내보내기 |
references/troubleshooting.md | LaTeX 오류, 애니메이션 오류, 일반적인 실수, 디버깅 |
references/animation-design-thinking.md | 애니메이션 vs 정적 표시 시기, 분해, 페이싱, 나레이션 동기화 |
references/updaters-and-trackers.md | ValueTracker, add_updater, always_redraw, 시간 기반 업데이터, 패턴 |
references/paper-explainer.md | 연구 논문을 애니메이션으로 변환 — 워크플로우, 템플릿, 도메인 패턴 |
references/decorations.md | SurroundingRectangle, Brace, 화살표, DashedLine, Angle, 주석 수명 주기 |
references/production-quality.md | 코드 전, 렌더 전, 렌더 후 체크리스트, 공간 레이아웃, 색상, 템포 |
창의적 분기 (사용자가 실험적/창의적/독특한 출력을 요청할 때만 사용)
사용자가 창의적이거나, 실험적이거나, 또는 틀에 박히지 않은 설명 방식을 요청한다면, 전략을 선택하고 애니메이션을 디자인하기 전에 그 이유를 생각하세요.
- SCAMPER — 사용자가 표준 설명에 대한 새로운 시각을 원할 때
- 가정 뒤집기 — 사용자가 일반적인 교육 방식을 도전하고 싶어할 때
SCAMPER 변환
표준 수학/기술 시각화를 가져와 변환하세요:
- 대체: 표준 시각적 은유를 대체 (수직선 → 구불구불한 길, 행렬 → 도시 격자)
- 결합: 두 가지 설명 접근법을 결합 (대수적 + 기하학적을 동시에)
- 역전: 결과에서 시작하여 공리까지 분해하며 거꾸로 유도
- 변형: 매개변수를 과장하여 그것이 왜 중요한지 보여줌 (학습률 10배, 표본 크기 1000배)
- 제거: 모든 표기법을 제거 — 순수하게 애니메이션과 공간 관계로만 설명
가정 뒤집기
- 이 주제가 일반적으로 어떻게 시각화되는지 '표준'을 나열 (왼쪽에서 오른쪽, 2D, 이산적 단계, 형식적 표기법)
- 가장 근본적인 가정을 선택
- 그것을 뒤집기 (오른쪽에서 왼쪽 유도, 2D 개념의 3D 임베딩, 단계 대신 연속적 변형, 표기법 제로)
- 뒤집기가 표준 접근법이 숨기는 것을 무엇을 드러내는지 탐구