X Motion: Prism は何をしますか?
Prism はコア x-motion メソッドのテーマです。そのメソッド(ブリーフ、テーゼ、ストーリーボード、アニマティック、プロダクション、境界のある批評)に従ってください。このファイルは、テーマを認識可能にし、誠実に保つためのアートディレクション、物理、サウンドを追加します。
ビジュアルテーゼ
淡いスタジオで静物のように撮影することで、1つの光学現象を正確で静かに不思議なものに感じさせ、観客に光が実際にどのように振る舞うかに気づかせる。
- 1作品につき1つのヒーロー現象。 分散、コースティクス、レンズ像、全反射、フレネルエッジ。その他はすべて、それが着地するための静かな表面です。
- 物理が色の配置を決める。 世界は無彩色です:紙、石、グラファイト。スペクトル色は、波長が分離する場所(プリズムを出る扇形、レンズのフリンジ、コースティクスの縁)にのみ現れ、それ以外の場所には現れません。
- 明るさがムードを作る。 これは暗い宇宙空間のテーマの正反対です。影は柔らかなグラファイトで決して黒くならず、ハイライトは光で決してネオンになりません。
- カメラは三脚固定。 固定されているか、かろうじて知覚できるプッシュだけ。現象が動き、観察者は動きません。
パレット
| 役割 | Hex | 使用法 |
|---|---|---|
| 紙 | #f2efe9 | 支配的な表面、環境光 |
| 日陰の紙 | #d9d4cb | キーライトの当たらない領域 |
| 薄い石 | #e6e1d8 | 床、水たまり、台座(低周波ノイズで±3%変動) |
| グラファイト | #5d5b57 | 印刷線、接触影(20~60%の不透明度) |
| 濃いグラファイト | #3a3936 | 許容される最も暗い値、接触のしわにのみ使用 |
| 水の色合い | #d8e6e4 | 石の上に乗算して浅い透明な水を表現 |
| スペクトル | 計算値 | 波長からRGBへの関数からのみ、手動で選んだ虹色は不可 |
線形光で作業し、光のエネルギーを加算してからトーンマッピングし、sRGBに変換します。明るい地の上に加算的なスペクトル色を置くと彩度が低下するため、彩度を高く読み取らせたい場所では地を局所的に暗くし(ヒーローの周りに柔らかな影の領域を、線形で45~60%程度)、フレームの残りの部分は風通しの良い状態を保ちます。
光とマテリアル
- キーライト: 左上からの1つの柔らかい昼光、フレーム軸から約30~45°。影は長く、柔らかく、やや暖かい灰色。
- ガラス: 透明、無色、完璧。その存在は、後ろにあるものの屈折、薄いフレネル縁、1つの柔らかい窓の反射、そしてそれが投げるコースティクスまたはスペクトル光の4つだけで示されます。ベベルのグロー、着色ガラス、ブルームハローはなし。
- 屈折率: Cauchy、
n(λ) = A + B/λ²(λはµm)。クラウンガラス:A = 1.5046, B = 0.0042。分散が画面上で読める必要がある場合、Bを最大約3倍まで誇張し、その旨をノートに記載します。 - 紙と石: マット、非常に低コントラストなテクスチャ(輝度変動2~4%)、時間的に静的。細かい印刷線は、ソフトなフォールオフを持つ1.2~2 pxのグラファイト。
- 接触: 表面に触れるすべてのオブジェクトは、きつく暗い接触影と、広く柔らかい影の両方を得ます。これにより、ガラスが浮いているように見えず、設置されているように見えます。
構図
- 余白をたっぷりと:ヒーローはフレームの約3分の1を占め、残りは紙または石で、穏やかな光のグラデーションがあります。
- イベントを三分割線または黄金点上に配置し、作品が対称性についてでない限り、決して真ん中には置かない。
- 光で視線を誘導する:ビーム、転がる方向、またはさざ波は、見せ場が起きる場所に向かって進むようにする。
- フレームの端は静かに保ち、わずかに暗くする(照明から作られた6~10%のビネット。黒いリングではない)。
- テキスト、UI、ロゴ、装飾的なパーティクルはなし。現象にスケールの基準が必要な場合は、印刷されたグリッド、石の目地、または影を使用する。
モーションの語彙とタイミング
動詞: 入る、曲がる、扇状に広がる、掃く、焦点を合わせる、さざ波打つ、落ち着く。 動く名詞: 光、水、単一のオブジェクト。カメラと被写体が同時に動くことはありません。
| ビート | 9~10秒の作品における典型的な割合 | 動作 |
|---|---|---|
| 静止 | 10~15% | 空の、照らされたセット。観客に表面を読ませる。 |
| 到着 | 15~20% | 光またはオブジェクトが、減速するイージングで明確な経路に沿って進入する。 |
| 現象 | 35~45% | ヒーロー効果が現れ、ゆっくりと変化する(数度回転、転がる、さざ波)。 |
| 沈静 | 20~25% | 動作が物理的に減衰し(摩擦、ダンピング、波の拡散)、保持される。 |
| 解放 | 5~8% | 光が暗くなるか、画像が静止し、ループとオーディオテールが閉じられる。 |
- 物理的な閉形式のモーションを使用:転がりには一定の減速、沈静には減衰余弦波、広がるリングには
1/sqrt(r)振幅、回転にはイージング付き角度。 - ガラス内の光は、ビームヘッドをアニメートするとき、空気中よりも目に見えて遅く進む(
v_glass = v_air / n)。それは視聴者が感じ取る小さな真実です。 - 複数の短いジェスチャーよりも、1つの長いジェスチャーを好む。全回転はやりすぎ。スペクトルを掃くには4~10°で十分です。
サウンドパレットとミキシング
サウンドはガラス、空気、水であり、調律されています。硬くて清潔な表面を持つ部屋のように感じられるべきです。
- ガラスの部分音: いくつかの非調和部分音(打たれたガラスの場合、比は
1, 2.32, 4.25, 6.63付近)を持つモーダル合成。各部分音は独自の指数減衰を持ち、高次部分音ほど早く減衰します。 - 指でガラスをなぞる音: 0.3~0.6秒のゆっくりとしたスウェル、4~5 Hzのビブラート(±0.15%)、そして同じピッチのバンドパスノイズのささやきを伴う1つか2つのサイン波。
- 空気: バンドパス(300~2500 Hz)を通したピンクっぽいシード付きノイズ。非常に低く、ゆっくりと呼吸する。それは部屋の音であり、風ではない。
- 水: 泡の「プリンク」音は、30~80 msで周波数が約30~60%指数関数的に上昇するサイン波。柔らかい水音はローパスフィルターを通したノイズ。
- ハーモニー: 1つのキーを選んでそれにとどまる(オープンフィフス、テンションコード、リディアンカラー)。現象をピッチにマッピングする:スペクトル位置を音階度に、速度をフィルターカットオフに、停止を解決するチャイムに。
- 空間: すべての音声で共有される、1つのシード付き合成コンボリューションリバーブ(2.5~4.5秒、ダークニングテール)、ドライ/ウェット比約60/40。
- ターゲット: 約-18 LUFSの統合ラウドネス、トゥルーピークは-1.5 dBFS以下、0.3秒のフェードイン、そしてすべてのテールは終了0.4秒前に減衰。
テクニックレシピ
時間の純粋関数。 すべてのフレームは t からシーン全体を再計算する:オブジェクトのポーズ、ビームヘッド、波の位相。シード付き乱数のみ。
const mulberry32 = s => () => { s |= 0; s = s + 0x6D2B79F5 | 0;
let t = Math.imul(s ^ s >>> 15, 1 | s); t = t + Math.imul(t ^ t >>> 7, 61 | t) ^ t;
return ((t ^ t >>> 14) >>> 0) / 4294967296; };
解析的なシーン、少数のパス。 レイマーチングの代わりに、いくつかの解析的形状(平面、球、凸プリズムを平面の集合として)と交差させる。時間から導出された状態(角度、位置、光線経路)をJavaScriptで計算されたユニフォームとして渡す。フレームを、1つの分岐だらけのシェーダーではなく、小さな単一目的のパス(床、半解像度のライトフィールドをRGBA16Fターゲットに、その上にガラス)に分割する。
波長からのスペクトル色。 滑らかな解析的フィットを使用して、扇形がグラデーションの見本ではなく光として読まれるようにする。複数の波長サンプルを合計し、合計がニュートラルホワイトになるように正規化する。
float gauss(float x, float m, float s) { float u = (x - m) / s; return exp(-u * u); }
vec3 spectral(float nm) { // スムーズフィット、線形RGB、可視窓 372-712 nm
float w = smoothstep(372., 392., nm) * (1. - smoothstep(690., 712., nm));
return w * vec3(gauss(nm, 606., 46.) + 0.14 * gauss(nm, 420., 22.), // 赤は紫にも戻る
gauss(nm, 543., 44.),
gauss(nm, 452., 34.));
}
明るい地では紫の端は淡いラベンダーとして読まれます。それは正直なことなので、ブーストする代わりに、より暗い局所的な領域を与えてください。
波長ごとの屈折。 異なる屈折率(赤、緑、青またはそれ以上)で同じ光線を2回または3回トレースする。結果が一致するところでは、鮮明でニュートラルなディテールが得られます。結果が分岐するところでは、物理が置くまさにその場所に色収差フリンジが得られます。
vec3 col;
for (int k = 0; k < 3; k++) {
float n = 1.5046 + B * 3.0 / pow(LAMBDA[k], 2.0);
col[k] = traceThroughGlass(ro, rd, n)[k]; // ガラス内で屈折、ガラス外で屈折、床をサンプリング
}
シミュレーションなしのコースティクス。 いくつかの解析的な波から構築された水面 h(x, t) の場合、点の下の床に到達する光は 1 / |det(I + d · Hess h)| に比例する(ここで d は深さを屈折率で割った値)。ヘッセ行列を解析的に計算し(正弦波と放射状リングパケットの両方に閉形式がある)、特異点を 1 / sqrt(det² + ε²) で軟化させ、薄いスペクトル縁のために3つのわずかに異なる d で評価する。
平面上の光の線。 紙をかすめるビームは、その軸を横切る1Dガウス分布 exp(-(dist/w)²) と、より広くかすかなグローである。ビームヘッドは経路に沿ってイージングされた距離で前進し、急なエッジではなく短いスムースステップでカットオフする。
帯域制限された印刷。 最も近い線までの距離から、スクリーンスペースのフットプリント(交点の fwidth)に対してグリッド線を描画し、レンズ内部を含む任意の倍率で線が1.5~2 pxのソフトさを保つようにする。セルが数ピクセル以下に縮小したら、白紙ではなく、プリントの平均的なトーンにフェードアウトする。拡大されたインクには最小のソフトネス(幅の約半分)を与えるか、ボールレンズの下の線がかみそりのように鋭い楔形になるのを防ぐ。
float lines(vec2 p, float s, float w, vec2 fw) {
vec2 d = abs(fract(p / s + .5) - .5) * s, a = max(fw * .8, vec2(w * .55)), wd = max(vec2(w), a);
vec2 l = (1. - smoothstep(wd - a, wd + a, d)) * clamp(vec2(w) / wd, 0., 1.);
return mix(max(l.x, l.y), 4. * w / s, smoothstep(.18, .42, max(fw.x, fw.y) / s));
}
ガラスには屈折させるための暗いものが必要。 白いスタジオでは、完全な球体は乳白色になります。地平線近くに灰色の壁、1つのコンパクトなソフトボックス、そして暗いフラグを環境に与える。ボール内部の反転した地平線と窓がその形状を描き出す。fwidth が有効なままであるように、分岐なしですべての経路を計算し、解析的なカバレッジ(光線から中心までの距離と半径の比較、ピクセル単位)をアルファとして出力する。
トーンと仕上げ。 指数ショルダー 1 - exp(-1.85 x) は紙を #f2efe9 付近に保ち、コースティクスのピークは柔らかくロールオフし、その後sRGB。チャンネルごとのショルダーは明るいスペクトル帯域をパステルに漂白するため、色付きの光については、色相を保存するカーブ(最大チャンネルをトーンマッピングしてスケーリング)に向かって約半分のところでブレンドし、彩度でゲートして紙が影響を受けないようにする。完全に色相を保存する、またはバンドの色をシャープにすると、オレンジ、黄色、シアンがフラットな赤、緑、青のストライプに崩壊する。ファンを数値的に確認する:ファン全体のカラムをサンプリングし、色相が赤(約10°)から紫(約270°)まで一度だけ上昇し、ラップがないことを確認する。淡いグラデーションのバンディングを壊すためにのみ、静的なサブLSBディザ(±0.6/255)を追加する。フレームごとにアニメーションさせてはならない。
速度。 SwiftShader はソフトウェアレンダリングであり、シェーダー内のすべての命令(どのピクセルも取らない分岐を含む)にコストがかかる。各パスを単一目的に保ち、ソフトなライトフィールドは半解像度でレンダリングし、高コストなパス(ガラス、プリズム内部)はオブジェクトの投影バウンディングボックスにスキャップし、SRC_ALPHA, ONE_MINUS_SRC_ALPHA で床の上にブレンドする。ポリッシュする前に、1920×1080で1フレームあたりの秒数を測定する。fbmは最大5オクターブ。
決定論的オーディオグラフ。 Chromium は3つ以上の接続を1つの AudioNode に不特定の順序で合計するため、2つのレンダリングは約1e-6異なり、バイトチェックに失敗する。すべての音声を JavaScript で1つのステレオ Float32 ミックス(位相累積サイン波、シード付きノイズのRBJバイクアッド、サンプル正確なエンベロープ)に合成し、グラフはドライゲインとコンボルバーへの単一ソース、両方を1つのハイパス(2つの入力は可換)、次に穏やかなコンプレッサー(約2.5:1、-20 dBスレッショルド)、線形フェードにのみ使用する。
const M = A.mix(sr, D); // { L, R } Float32Arrays
A.glass(M, 6.6, hz(81), 0.15, { decay: 2.8, pan: 0.2 }); // JSで加算されるモーダル部分音
const buf = await A.render(M, { seed: 31, room: 3.4, wet: 0.45, fade: [8.25, 8.8] });
return A.master(buf, { lufs: -18, ceiling: -1.7 });
ページ内でのマスタリング。 startRendering() の後、バッファを測定し(K-ウェイト、ゲート付き積分ラウドネス、4倍オーバーサンプリングピーク)、ターゲットに達するための1つのゲインと、ピーク天井が要求する場合の低いゲインを適用する。決定論的でシンプル。
決定論的レンダリングチェックリスト
window.motionは、幅、高さ、持続時間、fps、そして最も美しいフレームのポスター時間を宣言する。renderFrame(t)はtのみからすべてのユニフォームを設定する。レンダリングモードではDate、performance.now、Math.random、タイマー、または累積状態は使用しない。- 遅くシークしてから早くシークすると、同一のピクセルが再現される。最初と最後にキャプチャされたフレームは有効。
- プレビューモード(
?render=1なし)はrequestAnimationFrameでループする。クリックすると、同じレンダリング済みオーディオバッファが同期して再生される。 renderAudioは JavaScript で音声をミックスし、シード付きコンボルバーを通る1つのソースをOfflineAudioContextでレンダリングする。2回の呼び出しはバイト同一のサンプルを返す(3つ以上の入力を持つノードはない)。- キューマップは、画像と音声で共有されるコード内の時間のテーブル(インパクト、ストップ、リリース)であり、リバーブテールは最後の0.3秒で-45 dB以下。
- ネットワーク、フォント、画像、サンプルはなし。すべてのテクスチャとサウンドはプロシージャル。
避けるべきこと
- フレーム全体に描かれた虹色のグラデーション、虹色のテキスト、虹色の「ホログラフィック」表面。
- ネオン、紫から青への「AI」グラデーション、黒い背景、レンズフレア、アナモルフィックなスジ。
- 光沢のある3Dレンダリングガラス:厚く明るいベベル、着色ガラス、HDRIクローム反射、すべてにブルーム。
- 接触影のない浮遊オブジェクト、物理的な原因から来ない色。
- カメラの軌道、高速カット、パーティクル、スパークル、シューッという音、ライザー。
- フレームごとのランダムグレインや、H.264圧縮後にストロボする1ピクセルの線。
- クリップするサウンド、キーと戦うコードスタック、最後で途切れるリバーブテール。