カートゥーン3Dストーリーショート(three.js + Remotion)
実証済みの例: 橋のために歌った男(The Bridge That Fell for a Song)。1831年のブロートン橋と74人の兵士がシンクロ歩行したことによる崩落を描いた、オリジナルの67秒ショートです。
- コード: Remotionプロジェクト内
src/videos/bridge/(コンポジションBridgeShort、1080x1920、30 fps)。 - スクリプト、音声、サウンド:
~/bridge-short/。 - スタイル調査:
references/。
スタイルの参考元は、非公開で研究されたチャンネルです(references/: STYLE_BIBLE.md、reports/*.md、frames/)。
- それらの動画は非公開の学習資料です。アップロード、公開、送信しないでください。
- スクリプト、キャラクター、カットをコピーしないでください。ストーリー、キャラクター、音声は常に私たち自身のものとします。
- ナレーションや説明でチャンネル名を決して言わないでください。
適用されるユーザールール:
- 動画にキャプションやラベルを入れない。
- 英語のみ。
- 音声: 一定のトーン。
- ジョークは調査済みの事実に基づく。
- 標準ミックス: 音楽 +3 dB、SFX -6 dB、音声はそのまま。
- 最終出力 2K 縦型: 1440x2560、
--scale 1.3333。 - Opus maxによる検証を毎回実施。
- すべてのステップで保存。
- スクリプトが承認されたら「Just do it」。
パイプライン
- トピックと事実。 物理的な因果関係を持つ驚くべき真実の物語を1つ選び(視覚的であること)、それを説明する簡単な日常的な類推を添える。
- 事実とその出典を
SCRIPT.mdの先頭に記述。
- 事実とその出典を
- スクリプト(約3.7語/秒、55~70秒)。橋のショートのビート構造を踏襲:
- フック: 一行で不条理な事実を述べる(「74人の兵士が橋を渡って歩いただけで鉄橋を倒した」)。
- 設定: 年、場所、誇り。
- アクション: 3~4ビートでエスカレーション、各ビートは少しずつ大きくなる。
- スナップ: 崩壊の瞬間。
- 無表情な二行: 「幸いにも…/不幸にも…」
- 解説: 日常的な類推(ブランコの子供)を通じた1つの物理概念。
- 結果: それが生み出したルール。
- コールバックのひねり: エンディング。
- 視聴者がすでに見ているものを画面上で説明しない。
- 音声。
voice.wavを録音または生成し、単語のタイミングwords.jsonを作成する(単語時間を含む任意の音声認識ツール)。- プロジェクトフォルダ(例:
~/bridge-short/voice/)に配置。 - 単語タイミングを手動で修正する。すべては words.json に合わせてタイミング調整される。
- プロジェクトフォルダ(例:
- ショットプラン を
story.tsに記述:templates/bridge/(最終的な橋のソース、Remotionプロジェクトのsrc/videos/bridge/と同じ)をsrc/videos/<name>/にコピーし、src/Root.tsxのBridgeShortの隣に新しいコンポジションを登録し、名前を変更する。SHOTS: id、a/b フレーム、ライト(昼/ゴールデンアワー)、群衆モード、ストーリー時間tau。XFADE: 場所/時間変更時のクロスフェード。FLASH_AT: フック後のホワイトフラッシュ。CAMS: ショットごとのキー{f, dur?, cut?, s: f => {pos, look, fov, roll}}。KICKS: 衝撃時のフリップシェイク。DOF/dofAt: ビートごとのレンズブラー。FOREGROUND: 近景フレーミング用小道具。- すべての視覚的反応は、そのワードの0~3フレーム前に発生させる。
- ワールド。
lights.ts:LIGHTSと、ライトごとのLOOKスカイ/リバー/雲のパレット。shade.ts: 2トーンシェーディングとuntone()。build.ts: 町、家、Kenney CC0キットのプロップ、色変更、カメラを遮るものの視線刈り込み。paint.ts: HD Canvas2D ペイントテクスチャ、継ぎ目は暗い色合いでペイント。world.ts: スカイシェーダー、フォグ = 水平線の色、リバー、フレームごとのポーズ、ショットごとに固定されカメラ相対の太陽。
- キャラクター。
toon.ts: Canvas2DPen描画API、600x1000 デザインキャンバス、足裏は y = 975、豆ヘッド、棒状の手足、プラムの可変幅アウトライン、表情ライブラリ。cast.ts: カメラ対面ビルボード、群衆、エフェクトカード、瞬き、歩行サイクル。すべてのビルボードはNOINKレイヤーに配置。cardshade.ts: シーンライトで照らされたカード、放射光なし。
- ポスト(
Bridge.tsx+ink.ts+lensblur.ts+grade.ts)。- コンポーザー順: インク → レンズプレ → レンズメイン → ブルーム → NEUTRAL トーンマップ → グレード(MSAA 4)。
- すべてのピクセルパラメータは出力高 / 1920 でスケーリング。
- サウンド(
~/bridge-short/audio/: timeline.py、sfx_gen.py、sfx.py、music.py、instruments.py、dsp.py、mix.py)。- イベントテーブル → 合成SFXと、音声に合わせてダッキングされたオリジナル楽曲。
- 出力: mix.wav(48 kHz、正確な長さ)、ステム、cues.md。
- サウンド作成前に画像のタイミング定数をロックする。後でタイミングを変更する場合はサウンドを再実行する。
- ルックチェック。
node scripts/bridge-stills.mjs out/<name>/x_ 100,400 0.5を実行。BRIDGE_ENTRY=src/sandboxes/<n>/index.tsxを設定してサンドボックスコピーをレンダリング。python scripts/sbs_sheet.py out.jpg --ours ... --ref ...で参照フレームとのサイドバイサイドを作成。- Opus max 検証者に送信: 1~3枚の画像、200ワード以内の判定。
- 最終レンダリング。
npx remotion render src/index.ts <Comp> out/<name>/video.mp4 --codec h264 --crf 16 --scale 1.3333-map 0:v:0 -map 1:a:0でミックス(Remotionは無音のオーディオトラックを書き込む)。- QA:
python scripts/short_qa.py final.mp4 out/<name>/qa shots.jsonで全フレームの黒/白/フリーズ/ポップフレーム、ラウドネス、シートをチェック。 - 問題が見つかれば修正し、詳細なOpus監査を実行。
- 納品。 最終的なmp4をSendUserFileで送信、メモリを更新、メモを書き込む。
最終ルック値(橋の4回の検証ラウンド後。すべて templates/bridge/ 内)
新しいショートは常に templates/bridge/ から開始(src/videos/<name>/ にコピー): ルックはこれらの値に、ストーリーは story.ts / build.ts レイアウト / cast.ts の役割に宿ります。最終的なOpus maxスコア: カラーデイ7、ゴールデン5-6、ライティング5-6、インク6、テクスチャ5-6、キャラクター7、深度6-7、構図6-7(初期の5/3/4/5/4/7/4/6から改善)。
- ライトプリセット(
lights.ts、太陽はカメラ相対でショットごとに固定):- デイ: az 75 / el 48、ライト [1.58,1.5,1.33]、シェード [.30,.29,.36]、リフト [.05,.06,.11](影のみクールティント)、スカイ上部 #3e7fd2 → 水平線 #b8d0ec、フォグ = 水平線、25→300 m、uSat 1.08、60 m 先で約15%の青いヘイズ。
- ゴールデン: az 6 / el 7(逆光の低い太陽)、キーは #FFB36B ×1.5 方向、紫がかった青の影(ファサード約 #444380)、スカイ #ffc47c → #8a6f8a、桃色のフォグは50 m 先のみ、太陽のディスク #ffcf9e + ブルーム、接触ブロブ + 実際のカード影。
- アルベド(
paint.ts/build.ts): 落ち着いたレンガ / クリーム / 黄土色 / テラコッタの家、台座、コーニス、窓枠、フード、玄関ステップ、煙突 + 煙突キャップ、高さ 7 / 8.4 / 9.8 m。暖かいグレー/ベージュの石(「童話風」より彩度-35%)。黄土色の木製デッキ C* 約51-58、ほぼ黒の継ぎ目。鉄は暗く彩度低め。レモンやラベンダー色の面は決して使わない。 - インク(
ink.ts): #030303、近景(6 m)で5.1 px → 遠景(90 m)で3.3 px(1080x1920時)、35°から折り目は×0.8、深度ジャンプは1%から、フォグティント0.3は遠景のみ。キャラクターカードはNOINKレイヤー(独自のプラムインクを持つ)。 - レンズ(
lensblur.ts+story.tsのdofAt): 1080p での cInf px: フック/リバー CU 15-16、クローズアップ 12-14、MS 10-12、パーク 7、ゴールデンスウェイ 5、ワイド/航空 0。最前列の目に焦点を合わせる。 - ポスト(
Bridge.tsx): インク → レンズプレ → レンズメイン → ブルーム(thr 1.0、int .5、6レベル、半径 .6)→ NEUTRAL トーンマップ → グレード。MSAA 4。フィルムグレインは存在するがオフ(参照にはグレインなし。グレインによりファイルサイズが4倍になる)。 - キャラクター(
toon.ts/cast.ts/cardshade.ts): 豆ヘッド h/w .94、プラムインク #241726、目の間隔 .26 W、赤面なし、14種類の表情。大人は3.5頭身。歩行バウンド5%、傾き1-7°、一歩0.8 m。瞬き0.5-2.3秒。密着影は足元に約.5、デイ時は太陽方向に尾。ゴールデン時は内側のみのリム(オフセットした外側コピーは決して使わない)。 - カメラ(
story.ts): 大きなジャンプでカット、スムーサーステップグライド 18-40 f、すべてのホールドはクリープ(静止ホールドは4 f以上禁止)、衝撃時7 fで減衰するフリップキック、4-4.6°のロール、約1/3のショットに前景プロップ(FOREGROUND)。
ルックターゲット(参考文献から測定。references/reports/ 参照)
- インク:
- ワールド線: 1080幅で約3 px、ほぼ黒 #0b0a0c、距離にほぼ一定。シルエット、深度ジャンプ、法線の折り目のみ。壁/床の継ぎ目や水平線には線なし。キャラクターカードはワールドインクで輪郭を取らない。
- キャラクターインク: 暗いプラム #201628-#2f1d28、下部/影側で太め。
- 色:
- デイの中央ルーマ約.57。非インク p5 約.23(つぶれ黒なし)。ライトクロマ C* p90 約55。デイスカイ上部約 #5e93d9、水平線は1.28倍明るい。
- ゴールデン: 桃色の水平線 #ffd08a、紫がかった青の影(茶色は決してなし)、逆光の太陽。
- 深度:
- DOFは画面時間の約1/3(CU、MS、インサート)、1080p で cInf 10-16 px、目に焦点。導入とワイドショットはシャープに。
- フォグ = 水平線の色、デイ 25→420 m、ゴールデン 20→360 m。
- ブルームはHDR放射光のみ: しきい値1.0。
- カメラ:
- 大きなジャンプではハードカット。それ以外はすべて18-40 fのスムーサーステップグライド、720p でピーク ≤ 25 px/f。
- すべてのホールドは0.15-0.35%/fで押し込み、パンチワードでは0.6%/f。
- ロールは4-5°。
- 手持ち風フロートなし。インパクトシェイクは毎フレーム符号を反転し、7 fで減衰。
- キャラクター:
- 約3.5頭身、脚は1.4 HH。
- 棒状の手足は頭幅の約0.055、インクドットの手。
- 豆ヘッド(h/w 約0.93、あごが狭く、頭頂が尖っている)。
- 赤面や目のハイライトなし。顔の明るさ約.93。
- 歩行バウンド 3-7%、傾き 1-7°、足は接地。
- 0.5-2.3秒ごとに瞬き、4 f持続。
ルックマッチループ(橋のルックがどのように達成されたか。「〜のように見せる」パスに再利用)
- 最初に参照を測定。 トピックごとに1つの分析エージェント(モーション、深度、テクスチャ、キャラクター、ライティング、アウトライン、グレード)。各エージェントは数値を記述し、形容詞は避けて
references/reports/<topic>.mdに出力。共通ブリーフ:compare/CONTEXT.md。レポートは以降のすべてのエージェントにとっての真実の情報源。 - サンドボックス、ファイルごとに1つの所有者。 プロジェクトフォルダを
src/videos/<name>_{cam,world,mat,char,post}にコピーし、エントリsrc/sandboxes/<n>/index.tsxを作成(メインと同じindex.tsx、インポートパスのみ変更)。橋での所有権の例:- cam: story.ts(カメラキー、カット、キック、DOFテーブル、前景プロップ)
- world: world.ts、lights.ts、shade.ts、grade.ts(太陽、スカイ、フォグ、リバー、色、グレード)
- mat: paint.ts、build.ts(ペイントテクスチャ、建物、プロップ)
- char: toon.ts、cast.ts、cardshade.ts(キャラクター描画、ポーズ、カードライティング、FXカード)
- post: ink.ts、Bridge.tsx、lensblur.ts(アウトラインパス、コンポーザー、レンズブラー、ブルーム)
エージェントは自分のサンドボックス内の自分のファイルのみを編集し、
BRIDGE_ENTRY=src/sandboxes/<n>/index.tsx node scripts/bridge-stills.mjs out/<name>/<n>/x_ <frames> 0.5でスチルをレンダリング。
- マージ
python scripts/bridge_merge.py [cam,world,mat,char,post](メインをbackup/bridge_<time>/にバックアップし、所有ファイルのみをコピー)。その後npx tsc --noEmit(プロジェクトフォルダにフィルタリング)、メインからすべてのサンドボックスを再同期(cp -f src/videos/<name>/* src/videos/<name>_<n>/)してから次のラウンドへ。 - 検証 は新しいOpus maxエージェントで行う: サイドバイサイドシート(
python scripts/sbs_sheet.py out.jpg --ours a b --ref r1 r2)、各領域を10点満点でスコアリング(カラーデイ/ゴールデン、ライティング、インク、テクスチャ、キャラクター、深度、構図)し、フレーム番号付きの修正リストを作成。各修正をファイル所有者にマッピングし、その所有者のエージェントをSendMessageで再開(コンテキストを維持)。橋のスコア: ラウンド1 5/3/4/5/4/7/4/6 → ラウンド2 5/4/5/6/4/7/6/6 → ラウンド3 はノート参照。 - 所有者間の契約はエクスポートされた定数に存在する(例: ink.ts の
NOINKレイヤー、story.ts のdofAt/FOREGROUND、lights.ts のLIGHTS/LOOK)。契約を変更する場合は、それを読むすべての所有者に伝えること。
落とし穴
- Kenney nature-kit マテリアルはティール色: build.ts でマテリアル名で色を変更する。
- カメラが家の中に入り込む: build.ts/world.ts の視線刈り込みが、カメラレイを遮るものをすべて除去する。
- 同じマージされたエフェクトパスでインクとDOFを一緒に使うと上書きされる。インクはブラーの前の独自のパスでなければならない。
- ピクセル単位のポストパラメータは解像度に合わせてスケーリングする必要がある: スチルは0.5倍、最終は1.333倍。R3Fはdprを1以上にクランプするため、
--scale 0.5のスチルでも1080x1920バッファがレンダリングされる。 - ディスク: すべてのRemotionバンドルは
public/(約1.3 GB)をtemp folder\remotion-webpack-bundle-*にコピーし、削除しない。橋のパス中に60+ GBがシステムドライブを満たし、レンダリングがENOSPCで停止した。常にexport TEMP='<big drive>/remotion-tmp' TMP='<big drive>/remotion-tmp'でレンダリングし(bridge-stills.mjs で自動設定)、共有テンポラリフォルダの古いバンドルフォルダを削除する前にユーザーに確認する(自動モードは掃引をブロック)。/remotion-tmp も同様にいっぱいになる(橋の4ラウンド後で約500フォルダ/110 GB): プロジェクトが完了し、レンダリングが行われていない場合は、そこにあるremotion-webpack-bundle-*とpuppeteer_dev_chrome_profile-*フォルダを削除する。 - JSの文字列では
"<big drive>/remotion-tmp"と書き、"<big drive>\remotion-tmp"(\rは復帰文字になる)と書かないこと。 - Remotionは無音のオーディオトラックを書き込む:
-map 0:v:0 -map 1:a:0でミックス。 - サブエージェントはこのハーネスではレポートファイルを書き込めない: 150ワード以内の最終メッセージを依頼し、自分で
out/<name>/<n>/REPORT.mdに保存する。 out/内のスクラッチ.tsファイルはtscを壊す:.txtと命名する。- 2Kレンダリングは約4 fps(67秒で約10分)。0.5倍のスチルは約40秒のバンドル後、各3-8秒。
- 2.5%のフィルムグレインにより2Kファイルが約250 MBから910 MBになり、YouTubeでぼやける。参照にはグレインなし。オフのままにすること。
検証者がキャッチした判読性の罠(新しいプロップ/ショットごとにこれらをチェック)
- 子供の後ろで消える一本のロープとして描かれたブランコは、吊るされているように見える。 常に二本のロープで幅広の板を支え、子供はその間(
toon.tsのswingKid)、脚が弧を描くフレーム(両端にAフレーム)。 - レンズから約2 m未満のプロップや浮遊物は、フレーム端で巨大な切り取られたブロブになる。カメラが動くとき、新しい位置の近くにあるすべてのプロップを再チェックする(リバーカメラが浮かぶ帽子の中に移動した)。
- フレーム端で切れた前景の茂みは「緑のボール」に見える。前景プロップは認識可能であるか、または削除する。
- 旗: 赤+黄色の星/ダイヤモンドはベトナムのものに見える。時代に合った旗を使用する(1831年のイングランドには聖ジョージ十字)。
- 痛み
…(翻訳のために省略)