Communitygithub.com

Blender 제품 영상

사운드 없이도 이해되는, 텍스트 중심의 사일런트 제품 영상을 제작합니다. 사실적인 Blender 씬이 하나의 시각적 은유를 전달하고, 2D 블록 그리드 결말이 헤드라인과 콜투액션(Call to Action)을 철자합니다. 블렌더(bpy), Python 및 ffmpeg를 이용해 코드로 제작되며, GPU가 없는 머신에서도 작동합니다.

Blender 제품 영상란 무엇인가요?

이 스킬은 코드 기반의 완전한 파이프라인을 제공하여, 45~75초 길이의 사일런트(sound-off) 제품 영상을 제작합니다. Blender(bpy)와 ffmpeg를 사용하여 사실적인 3D 씬(잔디, 나무 문, 실제 하늘)을 구축하고, 하나의 시각적 은유를 통해 제품 메시지를 전달합니다. 텍스트 오버레이가 영상의 설명을 보완하며, 영상의 끝부분은 색상 블록 격자로 전환되어 헤드라인과 콜투액션을 보여줍니다. 특히, GPU가 없는 CPU 전용 환경에서도 효율적으로 렌더링할 수 있도록 설계되었습니다. 그라운드 잔디와 움직이는 오브젝트를 분리하여(2패스 렌더) 렌더링 시간을 단축하고, 애니메이션을 키프레임 없이 순수 시간 함수로 구현하여 중단된 렌더를 이어서 할 수 있습니다. 최종 compositing에서 2D 카메라 움직임을 시뮬레이션하여 실제 3D 카메라 이동 없이도 다이내믹한 느낌을 줍니다.

지원 대상~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/Ameliawampler/blender-product-video/tree/HEAD

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

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

문서

Blender 제품 영상은(는) 무엇을 하나요?

소리 없이도 이해되는, 45~75초 제품 영상을 위한 방법과 실제 동작하는 예제입니다. 사실적인 셋(잔디, 나무 문, 실제 하늘)이 하나의 시각적 은유를 전달합니다. 짧은 텍스트 오버레이는 화면만으로는 전달하기 어려운 내용을 말해줍니다. 영상의 끝은 평평한 컬러 블록 격자로 변하며, 해당 블록들이 뒤집히면서 헤드라인과 콜투액션을 철자합니다.

모든 것은 코드로 이루어집니다: 셋, 애니메이션, 합성. GUI는 전혀 열지 않습니다.

이 폴더의 구성

경로설명
film.json팔레트, 타이밍이 포함된 오버레이 텍스트, 엔딩 라인. 먼저 수정하세요.
scripts/blender/build.py셋: 헤어 입자 잔디가 있는 언덕, 문, 서리 낀 블록, 하늘, 헤이즈, 렌더 설정.
scripts/blender/mascot.py예제 캐릭터: 울타리 기둥 위에 앉을 수 있을 만큼 작은 복셀 올빼미.
scripts/blender/film.py샷, 카메라, 프레임별 애니메이션. plates 및 layers 렌더링.
scripts/post/comp.py합성기: plates + layers, 2D 카메라 움직임, 텍스트, 그레이딩, 2D 블록 엔딩, ffmpeg 인코딩.
assets/두 개의 하늘 플레이트(황금빛, 흐림). 직접 교체하세요.
examples/이 파이프라인으로 제작된 영상의 프레임 예시.

예제 영상은 "The Gate"입니다: 동일한 블록들이 열린 문을 통해 일정한 속도로 굴러 들어오다가, 크기가 다양해지고, 마침내 떼를 이룹니다. 문이 닫히고, 그 후 블록들은 통과되거나, 계산되거나, 멈춰집니다. 구조 참조용으로 사용하고, 제품에 맞는 은유로 교체하세요.

작업 흐름

다음 순서대로 진행하세요. 각 번호 단계에서 승인을 받은 후 다음 단계의 렌더링 시간을 투자하세요.

  1. 브리프(Brief). 각각 한 문장씩: 대상, 문제, 전환점, 약속, 콜투액션. 영상 길이(45~75초), 화면비율, 재생될 환경을 결정합니다. 음소거 재생을 가정합니다.
  2. 은유(Metaphor). 문제에 대한 하나의 물리적 그림과 제품에 대한 그 그림의 변화 하나를 고릅니다. 한 장소, 하나의 주요 소품, 한 종류의 움직이는 오브젝트. 설명이 필요하면 다시 고르세요.
  3. 비트 시트(Beat sheet). 6~8개의 샷. 각 샷마다: 지속 시간, 움직이는 것, 오버레이 라인 (8단어 미만, 하나의 아이디어), 카메라 위치와 렌즈. 문제 액트는 차갑고 흐린 빛, 제품 액트는 따뜻한 빛. 표로 만들어 승인을 받으세요.
  4. 캐릭터(선택 사항). 작은 주인공은 시선이 머물 곳을 제공합니다. 모델링 전에 평면 스케치로 3~4개의 옵션을 제시하세요. 셋과 크기를 맞추세요: 주요 소품 위에 들어맞아야 합니다. 간단한 원시 형태로 만드세요(올빼미는 1cm 큐브입니다).
  5. 코드로 셋 만들기. build.py를 수정하세요. 미터 단위를 유지하고 주요 소품을 원점에 두세요. 각 샷의 스틸 한 장을 낮은 샘플로 렌더링하고, 애니메이션 전에 모두 확인하세요.
  6. 애니메이션. film.py에서 각 샷은 setup_X(오브젝트를 한 번 생성)와 update_X(t) (영상 초 t에 모든 것을 배치)를 가집니다. 순수 시간 함수이며 키프레임이 없으므로, 어떤 프레임이든 단독으로 렌더링할 수 있고 중단된 렌더는 중단된 지점부터 재개됩니다.
  7. 2패스 렌더. python scripts/blender/film.py plates, 그 다음 ... layers. 아래 참조.
  8. 합성. python scripts/post/comp.py out.mp4 --draft로 빠른 확인(매 6번째 프레임), 그 후 --draft 없이 실행. 엔딩 튜닝 중에는 --only-ending을 사용하세요.
  9. 확인. 각 오버레이의 중간 지점에서 스틸을 뽑아 확인: 텍스트를 읽을 수 있는지, 텍스트가 지칭하는 것이 프레임 안에 보이는지, 샷 간에 튀는 것이 없는지. 문제가 있는 샷만 수정하고 다시 렌더링하세요(해당 샷의 layers/ 파일을 삭제).

2패스 렌더

사실적인 잔디는 느립니다. 움직이는 오브젝트는 저렴합니다. 그래서 분리하여 렌더링합니다.

  • Plates. 각 샷의 전체 셋(잔디, 소품, 하늘)에 대한 스틸 하나, 예제에서는 1280x720, 36 샘플. 빛이 변하는 샷은 합성기가 크로스페이드하는 두 개의 플레이트를 가집니다.
  • Layers. 움직이는 것만, 투명 배경, 낮은 해상도와 샘플로. 지면은 섀도우 캐처이므로 오브젝트가 그림자를 드리웁니다. 정적 소품은 홀드아웃이므로 오브젝트가 그 뒤를 올바르게 통과합니다. 하늘은 조명을 위해 남겨두되 카메라에서는 숨깁니다.
  • Compositor. 레이어를 플레이트 위에 놓고, 샷별로 느린 2D 푸시 또는 드리프트로 카메라 움직임을 가짜로 만듭니다. 고정된 3D 카메라가 플레이트를 재사용 가능하게 만듭니다.

세 가지 요소가 비용을 낮춥니다:

  • 루프(Loops). 샷이 일정한 흐름이라면, 움직임을 주기적으로 만들고(간격 0.84m, 속도 0.84m/s는 매초 반복), 한 주기만 렌더링합니다. film.py와 comp.py의 LOOP가 이러한 샷을 나열합니다.
  • On twos. 레이어는 매 두 번째 프레임(STEP = 2)으로 렌더링되고 유지됩니다. 스톱 모션처럼 읽히며, 작은 블록 오브젝트에 적합합니다.
  • Resume. 파일이 존재하면 모든 프레임을 건너뜁니다.

규모 참고: 예제 영상(51초 3D + 12.5초 엔딩)은 8개의 플레이트와 456개의 레이어 프레임입니다. CPU 전용으로 렌더링되었습니다.

2D 엔딩

comp.py가 Blender 없이 직접 그립니다. 팔레트 색상의 64x36 둥근 사각형 격자가 마지막 3D 프레임 위로 6열 너비로 날아들고, 카메라는 64개 열이 모두 보일 때까지 뒤로 물러난 후, 대각선 파동이 각 블록(중간 지점에서 색상이 바뀌며 수직으로 0으로 스쿼시되었다가 다시 펼쳐짐)을 최종 색상으로 뒤집습니다. 최종 색상은 3x5 픽셀 폰트에서 비롯되므로, 블록이 텍스트가 됩니다.

카피 계획 시 제한 사항: 최대 4줄, 각 줄 12자(11자가 더 좋아 보임), 대문자, 숫자, . - / !. film.json의 ending에 그리드 행과 팔레트 키로 설정하세요.

film.json 편집하기

  • palette: 7개의 16진수 색상. primary, accent, warm, soft, deep, paper(엔딩과 기본 블록의 배경), alarm("문제 발생" 색상).
  • overlays: [시작, 끝, "텍스트", x] (영상 초 단위). x는 선택 사항으로, 피사체가 가운데 정렬 텍스트에 가려질 때 텍스트의 수평 위치(0~1)입니다. 두 줄은 \n을 사용하세요.
  • ending: 블록이 철자할 라인들.
  • font: 오버레이용 .ttf 또는 .otf 경로. 대체 폰트로 Inter, DejaVu, Helvetica 또는 Arial이 사용됩니다.

샷 지속 시간은 film.py와 comp.py 상단의 SHOTS에 있습니다. 동일하게 유지하세요.

설정

python -m venv venv && . venv/bin/activate
pip install bpy==5.3.0 numpy pillow     # bpy는 Blender 휠; 일치하는 Python이 필요합니다.
# ffmpeg는 PATH에 있어야 합니다.

TEST=1 python scripts/blender/film.py plates    # 480x270, 샷당 한 프레임, 몇 분 소요
TEST=1 python scripts/blender/film.py layers
python scripts/post/comp.py draft.mp4 --draft

FILM_OUT=/some/dir는 plates/와 layers/를 이 폴더 대신 해당 디렉토리에 씁니다. FILM_CONFIG는 다른 film.json을 가리킵니다. GRASS_NEAR 및 GRASS_MID(백분율)는 잔디의 밀도를 조절합니다. 휠 대신 데스크탑 Blender 사용 시: blender -b -P scripts/blender/film.py -- plates.

실제 시간을 낭비하는 함정들

  • 잔디 길이. 헤어 파티클 시스템의 normal_factor를 설정하면 hair_length가 초기화됩니다. hair_length를 마지막에 설정하지 않으면 모든 잔디가 수 미터 길이가 되어 필드가 모션 블러된 것처럼 보입니다.
  • 부모-자식 관계. 부모 설정은 matrix_parent_inverse를 설정하지 않으면 자식을 움직입니다. 힌지 부분이 소품에서 떨어져 나갈 수 있습니다.
  • 하늘. UV 실린더의 하늘 이미지는 늘어납니다. 대형 실린더에 미러링된 패널을 사용하거나, 카메라가 팬하지 않는다면 평면을 사용하세요. 실제 빛을 위해 물리적 태양을 유지하세요.
  • 피사체 위의 텍스트. 모든 오버레이를 그 아래 프레임과 확인하세요. 카메라를 움직이기 전에 x로 텍스트를 옮기세요.
  • 확대(펀치 인)는 물체를 숨깁니다. 오버레이가 무언가를 지칭한다면("차단됨."), 2D 크롭이 여전히 그것을 포함하는지 확인하세요.
  • 색상 탈색. AgX 아래에서 칠해진 표면은 브랜드 16진수보다 어두운 기본 색상이 필요합니다. 화면이나 정확한 색상으로 읽혀야 하는 모든 것은 emission을 사용하세요.
  • GPU 없음. 프레임별로 예산을 세우세요: 레이어 프레임 하나의 시간을 측정하고, 곱한 후, 해상도, 샘플 또는 샷 길이를 줄여서 맞추세요. 시간을 측정하지 않은 렌더를 시작하지 마세요.
  • 컨테이너 재시작. 긴 렌더는 중단됩니다. 파일 존재 시 건너뛰기 검사가 당신을 구합니다.

이 파이프라인이 하지 않는 일

상대방이 기대하기 전에 솔직히 알려주세요.

  • 움직이는 3D 카메라. 샷은 고정되어 있고 2D 움직임이 위에 추가됩니다. 실제 시차는 매 프레임 셋을 렌더링해야 하며, GPU가 필요합니다.
  • 모션 블러와 레이어의 24fps 모션. 하드웨어가 허용할 때 샘플을 높이고, STEP = 1로 설정하고 render.use_motion_blur를 켜세요.
  • 오브젝트는 잔디 위에 앉고, 잔디 안에 있지 않습니다. 잔디는 플레이트에 있기 때문입니다.
  • 사운드. 영상은 무음으로 작동하도록 제작되었습니다. 필요시 나중에 음악과 효과를 추가하세요.
  • 3D 세계의 화면, UI 또는 로고. 의도적으로 제외했습니다: 사실적인 필드 속 제품 UI는 가짜로 읽힙니다. 제품 시각 자료는 2D 엔딩이나 별도 컷에 넣으세요.

최종 품질 패스를 위해

1920x1080 이상, 128+ 샘플 및 노이즈 제거, GPU 렌더링(OptiX 또는 Metal), STEP = 1, 모션 블러 켜기, comp.py의 W, H를 일치하도록 높이세요. 프레임 번호별로 여러 머신에 분할하세요; 모든 프레임은 독립적입니다.

관련 스킬