Atlas フライスルー
ショットの最後に視聴者に何を発見させるかを選択します。静止画の前景のエッジ、開けた移動可能な空間、複数の奥行きにあるランドマークを調べてください。前景の物体を横にずれるように移動することで、スケール感がわかりやすくなります。逆アングルが必要な場合は、被写体の背後に何があるかの証拠が必要です。
認証済みの World Labs CLI、Python 3(NumPy 付き)、FFmpeg を使用します。新しいショット用のディレクトリで作業します。PREP に、このスキル内の scripts/prepare.py の絶対パスを設定します。JPEG画像とその出力解像度を指定します。
プロンプト拡張は、サポートビューと最終フライトに対してデフォルトで有効になっています。prepare.py の生成コマンドに --no-enhance-prompt を渡すと、そのパスではシーンプロンプトがそのまま使用されます。
python3 "$PREP" pose scene.jpg --resolution 1280 720 > pose-request.json
worldlabs tasks run images2PosedRGBD --request pose-request.json --wait --json > pose.json
シーンプロンプトとキーフレームを含む shot.json を作成します。各行は、正規化された時間、カメラローカル座標での XYZ 移動(右、上、後方)、正規化された画像空間でのエイム U と V(左上から)、ソースカメラ単位でのエイム深度、焦点距離倍率、バンク角度(度)を指定します。時間は 0 から 1 まで厳密に増加するようにします。推定深度を確認し、シーンのスケールに合った距離を選択します。以下の最小限の横移動が開始点です:
{"prompt":"日光が差し込む作業台と高い窓のある工房。","knots":[[0,0,0,0,0.5,0.5,2,1,0],[0.5,0.15,0,-0.12,0.53,0.5,2,1,0],[1,0.35,0,-0.25,0.57,0.5,2,1,0]]}
python3 "$PREP" angles shot.json --pose pose.json --supports 6 > supports-request.json
worldlabs tasks run atlasGenerate --request supports-request.json --wait --json > supports.json
worldlabs operations download "$(jq -er '.id' supports.json)" --out supports
フルレンダリングの前に、パス順にサポートビューを確認します。隣接するアングル間で同じランドマークを追跡します。フレームゼロで入力と完全に一致させるには、そこで元のポーズ済みカメラを使用します。
難しい移動のためのアンカー選択
パッセージ、オービット、リバースリビールの場合は、障害物の両側とターンの中間を偵察します。Viewfiner スタイルの静止画には Developer API を使用します。targetCameras を疎に設定し、returnDepth: true、enhancePrompt: true を指定して atlasGenerate を実行します。カバレッジが良好なシンプルな移動では、最初のサポートパスを使用できます。
最初のパスで一貫性がない場合は、同じカメラポーズで代替案を生成します。スパースなターゲット配列とシーンプロンプトは固定したまま、contextFrames に指定する信頼できる以前のポーズ済みビューを変えます。例えば、一方のパスでは入口側のビューを優先し、もう一方のパスでは出口側のビューを優先します。すべてのカメラと深度マップは同じワールド座標系に保ちます。
候補を、カメラ時間ごとに1列、パスごとに1行で配置します。各候補を左右のビューと比較します。連続した開口部、安定したランドマークのシルエット、妥当な前景深度、明確な視線を探します。カメラが近くを通過するサーフェスの深度を確認します。シーケンス全体で一致するビューを選択します。冗長または破損したポーズはスキップするか、本レンダリングに進む前に欠落しているアングルを偵察します。
混合選択を使用するには、各ピックを保存されたオペレーション内のゼロベースのフレームインデックスとして記録します。例えば、2つの6視点パスをダウンロードしてレビューした後、jq を使用して最終的なコンテキストを構築します。実際のピックに置き換えてください。同じ返されたフレームから、RGBアセット、深度アセット、カメラをまとめて保持します。
# 後で同じコンテキストを再構築できるようにピックを保存します。
echo '[["A",0],["B",2],["A",4],["B",5]]' > picks.json
jq -n --slurpfile a supports.json --slurpfile b alternate.json --slurpfile picks picks.json '
{A: $a[0].response.frames, B: $b[0].response.frames} as $runs
| [$picks[0][] as [$run, $i]
| ($runs[$run][$i] // error("不明なアンカー: \($run)[\($i)]"))
| {camera, imageAsset: {assetId: .imageAsset.assetId},
depth: {depthAsset: {assetId: .depth.depthAsset.assetId}}}]
' > anchors.json
レンダリングと比較
ショットのキーフレームから密なカメラリクエストを準備します。
python3 "$PREP" flight shot.json --pose pose.json --angles supports.json --frames 120 > flight-request.json
混合セットをキュレーションした場合は、ここでそれらのアンカーを置き換えます。これにより、最初のポーズ画像が選択したフレームと一緒に保持されます。
jq --slurpfile picks anchors.json '.contextFrames = [.contextFrames[0]] + $picks[0]' flight-request.json > selected-request.json
mv selected-request.json flight-request.json
完全なパスを1回のオペレーションで送信します。
worldlabs tasks run atlasGenerate --request flight-request.json --wait --timeout 1800 --json > flight.json
worldlabs operations download "$(jq -er '.id' flight.json)" --out frames
ffmpeg -framerate 24 -i frames/frames_%03d_image.jpg -c:v libx264 -pix_fmt yuv420p -movflags +faststart shot.mp4
開始、最長のベースライン、リビール、終了を確認し、クリップを再生速度で視聴します。移動がまだズームのように感じられる場合は、レンズを固定し、サポートされている前景エッジの近くで横方向の移動を増やします。連続しているように感じさせる2つの動きを結合する場合は、エンドポイントの位置、ヘディング、レンズ、速度を一致させます。オプションの --footfalls は、歩行ショットに微妙な上下動を追加します。
アンカーセットを比較する場合、contextFrames のみを変更して、同じ密なリクエストを2回レンダリングします。偵察中に軌道を修正した場合は、修正した軌道で古いアンカーを再実行します。リクエストごとに異なるオペレーションを使用し、リクエストを保存し、contextFrames を削除しても同一のJSONになることを確認します。同じタイムスタンプで同期されたフレームを表示します。特にターンやリビールの部分で確認します。プロンプト拡張が有効な場合、両方のレスポンスの promptUsed を確認します。選択された画像によって拡張された説明が変わることがあります。実効的なテキストも固定した状態での実験には、両方の実行で enhancePrompt: false を使用して、1つの説明を再利用します。独立したレンダリングでも結果は変わる可能性があります。
Tide Organ のビーチの例では、2回のAPIパスで20ポーズの40枚の静止画が生成されました。17のピックが、アプローチ、リブ付きアーチ、開けたサーフ、海岸の逆方向のビューをカバーしました。銅パイプは、沖へのターン中の連続性を判断するための有用なランドマークでした。