遠近法錯覚(Perspective Illusion)
templates/ 以下のテンプレートは完全な動作シーンなので、こちらをベースに始めてください。
street.html:日本の街並み(ポール、コーン、横断歩道、赤い空)market.html:日本のスーパーマーケット(通路、陳列棚、赤い買い物かご、照明列)
どちらもカメラリグ、タイムライン、イラストパスは共通です。異なるのはシーンセクションのみです。
セットアップ(プロジェクトフォルダごと)
mkdir -p ~/Movies/edits/<日付>-<名前>/stills && cd $_
printf '{"type":"module"}' > package.json && npm i [email protected] [email protected]
cp ~/simcraft/skills/perspective-illusion/templates/{street.html,render.mjs} .
node render.mjs street.html x --stills=0.2,1,2,4,6 # まずフレームを確認(stills/st_<t>.png)
node render.mjs street.html out.mp4 # 7秒ループ、1920x1080、4サブフレームモーションブラー(約2.5分)
手法の4つのポイント
- シーンを一つの長い軸に沿って配置する(通りや通路を -z 方向に奥へ伸ばす)。ポールや柱は同じx座標に並べ、建物や背面の壁は終端に置く。400m先からの2°望遠でこれらはすべて一つの断面に圧縮される。並んだポールは重なって一本に見え、長い側壁はエッジだけになる。
- カメラを決して傾けたり回転させたりしない。 常に軸に沿って真正面を向き、水平を保つことで垂直線が垂直のままになる。「見下ろし」「見上げ」は、ティルトシフトレンズのようにレンズシフト(
H、フレーム内の地平線位置)を使う。各ショットは{x, y(カメラの高さ), zf, W, fov, H, lay, cs}で定義される。 - ドリーズームとしてショット間をモーフィングする。
Wは焦点面zfでフレームに収まるよう固定され、fov が変化する。すべてのパラメータは全キーフレームを通じて単調なキュービックカーブで動作するため、速度が急変しない。 - 平坦な状態でこっそりと操作する。 コーンや買いかごなどのオブジェクトは、平坦なホールド中にのみカメラに向かって近づけたり遠ざけたりする。この動きは平坦な状態では目に見えない。これにより、一列に並んでいたものが斜めの配置(「前後が入れ替わる」)に変わる。また、平坦な状態ではオブジェクトを大きく描画することもできる(
cs)。
参照動画に合わせる方法(目測ではなく測定を)
- 各ショットのフレームを抽出する。その後、各ショットについて以下を測定する:
- 消失点と地平線の位置(
Hが求まる) - 幅が既知の2つの物体の位置(
xとWが求まる) - 横断歩道など、長さが既知の物体の手前側と奥側の位置(カメラの高さ
y、距離、fov が求まる) 計算された数値はテンプレートのコメントに記載されている。
- 消失点と地平線の位置(
- その動画のフレームからパレットをクラスタリングする(4フレームでk-means)。そして、その正確な色を使用する。
- 変更のたびに、同一タイムスタンプでのフレームを参照動画と並べて比較する。
イラストパス(なぜレンダリングではなく描かれたように見えるか)
このページは3つのパスをレンダリングする:カラーパス(2トーンのセルシェーディング)、ビュー空間法線と深度、そして太陽光のみのシャドウマスク。最後のシェーダーが3つの処理を行う:
- インク線:深度(2階差分。これにより、平坦な地面がエッジとして見えない)または法線が変化する場所に描画。線の太さはノイズで変化し、ルックアップ位置もわずかに揺れるため、定規で引いたような直線にはならない。深度しきい値は距離とともに大きくなる。
- ハッチング:影の領域のみに適用。冷たい色調と細かい斜めストロークで、表面がエッジオンに近づくにつれて薄くなる。
- 空(または天井):ジオメトリがない部分にベタ塗りで描画。
遭遇した問題と回避策
- ワンライナー文に
//コメントを追加するとscene.add(sun)が飲み込まれ、シャドウマスクが黒くなりすべてがハッチングされた。/* */を使うか、新しい行に分けること。 - 重なり合った同一平面の床が遠方でちらつく。床の部品は端と端で接するようにする。
- 壁に対して浅い角度で当たる光は、斑点状の自己影を生じさせる。キーライトは正面から約45°に保ち、フルハイトの柱や天井の照明器具が影を落とさないようにする。
- 生成画像や看板にテキストを入れてはいけない。看板は形状のみとする。
- すべてのフルレンダリングの前にスチルを確認し、モーションチェック(vox-explainer の
motion_check.py)を実行すること。