リアルな3Dショート動画(Blender + Python)
すべてのフレームは、ClaudeがPythonで構築したシーンの実際のBlenderレンダリングです。AI画像や動画モデルは使用しません。
最終出力:1080x1920、30 fps、H.264(最大30 Mbps)。パス:<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ごとに1回)
- 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つの質問を2ラウンド行い、その後音声の回答に応じて3ラウンド目を行います。blender-shorts/brand.json が存在する場合は、まず1つの質問:「前回と同じ設定?」(1行で表示)を「はい」/「一部変更」で尋ねます。「はい」の場合はラウンド3のトピック固有部分にスキップします。 推奨オプションを最初に表示。すべての回答を brand.json(チャンネル全体)とエピソードの episode.json に保存します。
ラウンド1:内容と話し方
- トピック:「3つ提案して」/「自分で決めている」(「その他」の下に入力)。提案は、画像で示せるからだや仕組みに関する質問で、YouTubeで独自の角度かどうかを確認。
- 音声:
- ElevenLabsの音声(推奨):ストックボイスで、スクリプトから正確な単語タイミングで生成。
- 自分の声をクローン(ElevenLabs):1〜3分のクリアな音声を1回アップロード。以降のすべてのエピソードでその声で話します。自分の声、または書面による同意を得た声のみ。
- 自分で録音する:スクリプトを録音。Claudeがクリーニングし、単語タイミングを見つけ、それに合わせて画像を構築。
- 音声なし、キャプションのみ:スクリプトは2.8語/秒でタイミング設定され、キャプションが焼き付けられ、
captions.srtにより後でエディターで正確なタイミングで録音または音声追加が可能。
- 長さ:30秒(初めてに推奨)/45秒/60秒。2.8語/秒で約80/120/165語。
- 参考動画:「いいえ、組み込みのスタイルルールを使用」(推奨)/「はい、ファイルまたはリンクを提供」(
measure.pyで計測、個人学習のみ)。
ラウンド2:見た目
- 見た目:スタジオ背景(推奨:単一のシグニチャーカラーを背景に、ジャンルのスタイル)/実写のフォトバックプレート(スタジアム、街並み、空を3Dの背後に)/ミックス(背景に、特定の場面で実写の場所)。
- 背景色(背景を使用しない場合はスキップ):ピーチ
#F2D7C9(これまでのもの)/ミント#CFE8DF/ディープネイビー#1F2A44/カスタム(16進数)。参照チャンネルの色は使用しない。 - メインキャラクター:「メインキャラクターはいますか?」(
references/characters.md)- リグ付きキャラクターを提供:.blend / .fbx / .glbファイル(Mixamo、Character Creator、ストア等)。
- 作成してもらう(持っていない場合に推奨):Blender内でMPFBを使って作成。アカウント不要、シャツにロゴを配置。
- 無料のリグ付きをダウンロード: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:音声:落ち着いたナレーター(デフォルトIDは
sound.py内)/「自分のElevenLabsライブラリから選択」(GET /v1/voicesでリスト表示、名前のみ)/音声ID(入力)。音声モデル:eleven_multilingual_v2(推奨:安定、最良の単語タイミング)/eleven_v3(より表現豊か、予測しにくい)。 - クローン:サンプルファイル(パス)を求め、
sound.py <ep> clone <files> --name "<その人の名前> voice"を実行。音声IDは保存され、以降のすべてのエピソードで再利用。 - 自分の録音:スクリプトが承認されるまで待つよう伝え、その後ワンテイクで録音(電話を腕の長さで、静かな部屋)、ファイルパスを指定。承認されたスクリプトに合わせて録音することで、画像と音声の同期を保つ。
- メインキャラクター、ラウンド2の回答に応じて:
- 提供:ファイルパス(テクスチャフォルダが別ならそれも)を尋ねる。
- 作成:年齢層、体型、髪型と服装スタイル(平易な言葉)を尋ね、その後MPFBのインストールを依頼。
- ダウンロード:2〜3の候補をオプションとして表示(名前、見た目、ライセンス、アカウントの必要性)、選択させる。
- すべての音声オプション:キャプションを焼き付け? はい/いいえ(音声なしの場合は常にキャプション)。
- すべてのオプション:音楽:なし、効果音とルームトーンのみ(初回推奨)/自分のトラック(ファイルパス、権利を確認)/YouTube Audio Libraryのトラック(ダウンロードしてパスを指定)。
これ以外は質問しない。以下のすべてにはデフォルトがあります。「特定のモデル」に関する質問:このパイプラインにはAI画像や動画モデルはありません。モデルに相当する選択肢は、レンダーエンジン(ラウンド2)、ElevenLabs音声モデル(ラウンド3)、およびスキルを実行するClaudeモデル(高努力のOpusが最適)です。
エンジンプリセット(ユーザーの選択設定、保持すること)
- EEVEE高速(デフォルト、
b3d.EEVEE_PRESETS['fast']):16サンプル、ハーフレイトレーシングとGI、1シャドウレイ。 RTX 3080で1080pで約0.9〜1.2秒/フレーム、highとの類似度99〜99.9%。 - Cycles高速(
b3d.CYCLES_PRESETS['fast']):32サンプル、1秒の時間制限、OptiXデノイザー、2〜3バウンス、Fast GI近似、パーシステントデータ。約1.7秒/フレーム。クローズアップでデノイザーのスメアが見える場合は、そのショットに2秒の制限を設定。 --quality draft | fast | highをレンダリング時に指定、再構築不要。エンジンはシーンごとに:setup_render(engine=...)、またはB3D_ENGINE=CYCLES python render.py <ep> buildで編集せずにA/B比較。1つのショート内でのエンジンの混合も可能(各ショットのフレーム範囲を独自の.blendからレンダリング)、ただし背景とグレードが一致していること。
パイプライン(各ステップ後に保存、ユーザーにはテキストの壁ではなくスチルを表示)
- トピックと事実。 すべての数値を調べ、出典とともに
episode.jsonのscienceに記述。疑わしい有名な数値には「科学者によると」を付ける。大きなチャンネルと同じトピックでも問題ないが、彼らの言葉は使わない。 - 参考動画の計測(ラウンド1で「はい」の場合のみ):
measure.py <folder> --out <ep>/reference.json。それ以外はstyle.mdのデフォルトを使用。 - スクリプトを
episode.jsonに(examples/episode.template.json):二人称、約2.8語/秒、選択された長さ、style.mdのビート形状。表示し、OKを待つ。OK後は「そのまま実行」でスチルまで。 - 音声とタイミング、ラウンド1の回答に応じて:
- ElevenLabs / クローン:
sound.py <ep> voice->audio/voice.wav、words.json、captions.srt。 - 自分の録音:ファイルを待ち、
sound.py <ep> own <file>(単語時間:faster-whisperがインストールされていればそれ、なければElevenLabs音声認識、なければ無音区間からの推定。推定がずれている場合はpip install faster-whisperを提案)。 - 音声なし:
sound.py <ep> captions->words.json+captions.srt("wps"2.8)。 その後shots.mdを作成:ビートごとに、フレーム範囲(単語時間から)、カメラ移動(ドリーイン/ホールド+クリープ/プルアウト/フライスルー)、各ホールド中に動き続けるもの。約7つのトランジションに1つまでのハードカット。
- ElevenLabs / クローン:
- 最初に9秒テスト。 ショート全体の前に1ビートをフルパイプラインでテスト:
b3dヘルパーを使用したscene.py。レンダリング、finish、measure.py、参考動画がある場合はcompare.py reference.json ours.json。差分がTODOリストになります。 カメラのジャークと横方向のドリフトが一致するまで修正(1軸、イーズ付きキー)。 - ワールドとキャラクター。 キャラクターを先に、
references/characters.mdのパスに従い、常にb3d.import_character(path, height=1.75)を通して行う:実身長にスケーリングし、床に足をつけ、余分なカメラやライトを削除し、ウェイト付きパーツをリグにバインドし、レポートを出力(リグタイプ、リグに追従しないパーツ、顔の形状 x/52、欠落テクスチャ)。レポートのすべての項目を修正し、その後ターンアラウンドスチルを表示、assets/host/host.blendに保存。ワールドはreferences/assets.mdから(ダウンロードリスト、ソース+ライセンス+サイズ、1回だけ質問)。ルール:実在するものがあればダウンロードし、モデリングしない。 - スチルと判定。
render.py <ep> still <frames...> --pct 50を各ビートに実行。その後、別のエージェント(Agentツール)をスチルとreferences/realism.mdとともに起動。10点満点でスコアを付け、最もリアルさを損なう3点を挙げる。修正、再レンダリング、再判定。8.5以上でのみレンダリング。 ユーザーにスチルとスコアを表示。「自動」エンジンの場合、EEVEEのショートカットで不合格となったショットはここでCycles高速に切り替え。 - レンダリング。
render.py <ep> framesをユーザーのターミナルパネルで実行(run_in_terminalを使用)。ライブバー(フレーム完了数、秒/フレーム、ETA)をユーザーが確認可能。<ep>/progress.jsonを読んで「どのくらい進んだ?」に回答。再開可能。その後render.py <ep> times;遅すぎる場合は、最も遅いフレームからreferences/render-speed.mdを下って作業。 - サウンド。
beds(ワールドごとのルームトーン)とsfx(各単語に対応:「bones」に「骨のノック」など)をepisode.jsonに記述。その後sound.py <ep> sfx(キーが必要。キーがない場合は効果音をスキップするか、ユーザーがaudio/sfx/<name>.mp3で提供するファイルを使用)とsound.py <ep> mixを実行。ミックスルール:音楽 +3 dB、効果音は半分、音声はそのまま。 - 仕上げ。
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ではフェイク)、ライト、1軸イーズドーリーカメラ、マテリアル、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 | シェル | 任意の動画のフレーム単位メトリクス;参照と自作の比較、TODOリスト付き |
scene.py は blender -b --factory-startup --python scene.py -- <skill>/scripts <ep>/scene.blend として呼び出されます。
examples/test-cell/scene.py から開始(ライトの後に shadow_catcher を呼び出す)。