스틱 크라우드 MV (페인팅 3D + 코드 군중)은(는) 무엇을 하나요?
example/에 작업 예제: "군중 속의 외로운 사람" — 베트남 책 거리에서 2컷(낮, 황혼), 비 오는 일본 쇼핑 거리 밤에 4컷, 그리고 카메라가 하늘로 올라가는 타임랩스 엔딩. 30초, 720프레임, 24fps.
이 스킬은 painted-3d-short(https://github.com/thuann-vn/claude-painted-3d-shorts) 위에 있습니다. p3d.py가 블록아웃을 만들고, 스틸을 렌더링하며, 페인팅을 투영하고 매 프레임마다 세터를 호출합니다. 먼저 그 스킬을 읽으십시오. 이 스킬은 사람을 추가합니다.
파일
tools/stick.py— 군중.setter = stick.make(globals(), "<location>")로 만들고render(SHOTS, [setter])에 전달합니다.tools/gait.py— 걷기 (numpy만 사용, Blender 없이 테스트 가능).tools/post.py— 렌더링된 프레임에 대한 피니싱 패스.example/scene.py,example/book.py— 두 세트와 그 쇼트.example/jobs.json— 재페인팅 프롬프트.example/paint/— 페인팅.example/m2m.json— 유휴 클립 (Mesh2Motion, CC0).
작업 순서
- 먼저 곡: 원하는 30초를 잘라내고, 가사 라인 시간을 찾고, 그에 맞춰 쇼트를 자릅니다(
scene.py와stick.py의CUT). - 페인팅에 사람이 없는 상태로 painted-3d-short와 똑같이 블록아웃 + 스틸 + 재페인팅 + 투영을 합니다.
- stick.py의
SHOTS에 각 쇼트를 단계화합니다: 주인공 시작 위치, 방향,walk또는stand, 얼굴 피치, 차선 반폭, 거품 반경, 가장자리에 서 있는 사람들, 옆길 걷는 사람들(cross). - 단일 프레임 테스트:
NTEST=2 STICK_OFF=<frame> blender -b --factory-startup -P scene.py -- --proj --shots 4. 결과를 확인합니다. - 전체 렌더링 (최대 3개의 Blender 프로세스),
post.py, ffmpeg + 곡 클립으로 합칩니다. - 부드럽다고 말하기 전에 측정하십시오: 쇼트별 연속 프레임 간 평균 절대 차이; 최대값 ÷ 중앙값이 약 2 이상이면 무언가 튀었다는 뜻입니다(해당 프레임을 찾아 확인합니다).
사람들이 어떻게 만들어지는지 (stick.py)
- 세트 내부의 실제 지오메트리이므로 페인팅된 거리가 올바르게 가립니다. 모든 사람의 팔다리 = 매 프레임마다 정점이 다시 쓰이는 6면 프리즘의 ONE 메시(numpy →
foreach_set). 머리 = 카메라 공간 3단계 셀 셰이더 + 뒤집힌 헐을 가진 구체. 200명의 사람이 EEVEE에서 1초 미만으로 렌더링됩니다. - 머리 중심은 목선 위에 있습니다(
neck + dir × radius × 0.86). 머리가 몸에서 떠 있을 수도 있습니다. - 조명: 위치별 램프 목록(위치, 색상, 강도). 각 머리는 합계를 객체 색상으로 가져오고, 가장 큰 채널로 정규화하며 클램핑하지 않습니다(클램핑은 모든 것을 흰색으로 만듭니다). 그림자 = 가장 가까운 위 램프에서 바닥으로 투영된 같은 팔다리 메시(길이 클램프) 또는 햇빛에서는 태양 방향; 부드러운 접촉 블롭도 추가됩니다.
- 우산(비): 사람당 8-패널 돔 객체, 객체 색상에서 색상 가져오고, 1/3은 투명 비닐; 오른팔은 자루를 잡도록 재포즈됨; 캐노피는 둥근 그림자를 드리웁니다. 주인공은 우산이 없습니다.
- 전화기: 왼손을 귀에 대고, 뺨에 붙은 얇은 판으로 밤에는 빛납니다.
- 비: 렌즈 앞에 적어도 1.9m 떨어진 얇은 카메라-대면 사각형 상자.
걷기 (gait.py)
모션 캡처를 선 인물에 적용하면 지저분해 보입니다(목에 뿌리를 둔 팔이 넓게 벌어지고 손이 시끄럽습니다). 대신 걷기는 절차적입니다:
- 발은 고정됨: 지지하는 발은 몸이 그 위로 지나가는 동안 제자리에 있고, 바닥에서의 위치는 걸은 거리에서 오므로 어떤 속도에서도 미끄러짐이 없습니다(측정 결과: 프레임당 < 0.2mm).
- 엉덩이는 지지하는 다리 위에서 높고 이중 지지 시 낮음; 무릎이 앞으로 향하는 2-뼈 다리 IK.
- 팔은 목에서 몸 가까이 매달려 다리를 상대로 흔들림; 머리는 안정적.
- 사양:
normal,stroll,brisk(보폭, 케이던스, 팔 스윙, 기울기가 사람마다 다름) 및hero(짧은 보폭, 고개 숙임, 팔 늘어뜨림). 실제 케이던스: 산책 80–105보/분, 보통 105–125, 빠름 125–140.
지불된 군중 규칙
- 쇼트 전체에서 보행자당 하나의 직선 차선. 쇼트 중 조향(주인공 주변, 렌즈 주변)은 사람들이 옆으로 돌진하게 만듭니다. 대신, 쇼트가 시작되기 전에 각 보행자를 쇼트 기간 동안 시뮬레이션하고, 한 번 주인공의 빈 원에 들어가거나, 렌즈에 너무 가까이 지나가거나, 렌즈와 주인공 사이에 서게 된다면 그의 차선을 옆으로 한 번 이동시킵니다.
- 루프는 시야 밖에서 감싸야 합니다. 카메라 뒤 약 6m에서 앞 50m까지 거리를 채우고 감싸는 부분에서만 페이드 아웃합니다. 화면 내에서 감싸는 것은 사람이 다른 곳으로 점프하는 것입니다.
- 화면 내에서 사람을 축소하거나 페이드 아웃하지 마십시오.
- "붐빈다"고 읽히는 밀도: 6m 너비 거리에서 미터당 2–2.7명.
- 두 개의 키프레임이 남아 있는 포즈 클립을 반복하면 인물이 떨립니다: 고정(
timeScale = 0). - 서 있는 사람은 결코 가만히 있지 않습니다: 호흡, 느린 체중 이동, 얼굴 돌리기.
- 커플은 같은 사양으로 반 주기 차이를 두고 나란히 걷습니다.
타임랩스 (전체 영화)
- 모든 쇼트에서 군중의 시계는 10배 빠르게 움직입니다(
LAPSE,warp()); 주인공만 실시간으로 살아 있습니다. 이 대비가 영화의 아이디어입니다. - 프레임당 6개의 서브 프레임 렌더링(
SUB; scene.py에서 쇼트의 프레임 수 × 6); post.py가 선형 광에서 평균을 내어 사람들은 선이 되고 조명은 밝게 유지됩니다. 30초 = 4320 렌더, 3개의 Blender 프로세스에서 약 25분.
페인팅 내부의 카메라 움직임
투영된 페인팅은 작은 전진 돌리만 견딥니다. 그러나 렌더 카메라는 페인팅 내부에서 자유롭게 TURN, ZOOM IN 및 ROLL할 수 있습니다: 순수 회전은 시차가 없습니다. stick.py의 CAMK는 쇼트별 키를 보유합니다 — (쇼트의 일부, 줌, 팬, 틸트, 롤, 주인공 조준) — p3d의 look() 이후에 적용됨; 팬과 틸트는 줌이 남긴 공간으로 클램프되고, 롤된 프레임은 그림 내에 머물기에 충분히 줌됩니다. 각 쇼트에 하나의 움직임과 그 이유를 부여하십시오:
- 그를 가까이서 시작하고, 틸트 업하고 뒤로 당겨 붐비는 거리를 드러냅니다;
- 그가 우리를 향해 걸어올 때 얼굴로 천천히 푸시인;
- 네온 사인에서 거리로 내려와 그를 찾을 때까지;
- 푸시인 중에 기울어진 지평선이 안정됨;
- 지나가는 우산을 가로질러 팬하여 그에게 멈춤;
- 위에서: 맨머리를 가까이서, 회전하며, 우산 위로 뒤로 당김;
- 엔딩: 하나의 매우 넓은 그림(14mm, 약 20° 위로 조준)과 그에게서 하늘로 틸트하는 28mm 렌더 카메라.
오빗이나 실제 크레인 움직임을 위해서는 해당 쇼트에 대해 추가로 넓은 그림을 페인팅하십시오.
피니싱 패스 (post.py)
정말 밝은 부분에 블룸, 비네트, 그레인(어두운 곳에서 더 강하게), 약간의 색수차, 느린 핸드헬드 드리프트(타임랩스에서는 제외), 각 컷에서 펀치인 + 플래시, 그리고 곡의 킥(오디오 저대역, 프레임별)에 작은 줌과 글로우 펄스. 모든 효과를 작게 유지하십시오; 함께 충분합니다.
음악
권리가 있는 음악을 사용하십시오; 이 저장소에는 오디오가 없습니다. CLIP=/path/clip.m4a python post.py는 킥 펄스를 위해 곡을 읽습니다. 이미 렌더링된 쇼트에 새 트랙을 맞추려면 트랙 위로 30초 윈도우를 슬라이드하고, 컷 시간에서 온셋 강도가 가장 높은 오프셋을 유지하십시오. 예제의 최종 컷은 coruscate의 "Thunder & Rain Inst. & Construction Kits"(https://ccmixter.org/files/Coruscate/61228), CC BY 3.0을 사용합니다.