X Motion · Orbit
Orbit 是 x-motion 的擴充,而非取代。請先執行核心方法(簡介、論點、故事板、評論),再使用此檔案進行美術指導與配方。此檔案專為 8–12 秒、1920×1080、30 fps 的影片而寫,這些影片由 renderFrame(t) 在 headless Chromium 中以軟體 WebGL 確定性渲染。
視覺論點
太空是黑色的,光才是事件。一個光源(太陽)以及它所觸及的材質:大氣、海洋、雲層、金屬。每部影片都圍繞著光抵達、掠過邊緣或掙脫束縛的那個單一瞬間建構。
沉穩自信,而非奇觀。畫面大部分是真正的黑色;主體是一個巨大、緩慢的質量(行星、衛星、保險庫門)以及一道細薄的明亮邊緣。如果一個畫面看起來像桌布或遊戲選單,請移除元素,直到它看起來像一台耐心相機拍攝的照片。
調色盤
線上性 HDR 中工作,並在最後進行色調映射;以下是供肉眼聚焦的顯示參照目標。
| 角色 | 十六進位 | 用途 |
|---|---|---|
| 真黑 | #000000 | 大部分畫面的 60–80 %。切勿用霧氣提亮。 |
| 虛空深藍 | #050b18 | 深空漸層,遠離任何光源。 |
| 深海軍藍 | #0b1a33 | 夜晚海洋、陰影中的金屬、「提亮」後的暗空。 |
| 瑞利藍 | #2f6fd8 | 晝側的大氣本體。 |
| 大氣青 | #8fd3ff | 菲涅爾邊緣、稀薄邊界線。 |
| 日出金 | #ffc46b | 太陽核心衰減、明暗界線、雲頂上的第一道曙光。 |
| 餘燼琥珀 | #ffa448 | 夜側的城市燈光(鈉燈)。 |
| 日冕珍珠 | #ece8de | 日冕、恆星、鈴鐺般的高光。 |
| 鈦金屬 | #8a8f96 | 刷紋金屬本體。 |
| 鎳金屬 | #c3c6c8 | 金屬高光、斜面平面。 |
| 香檳金 | #e9d4a6 | 金屬上的暖色鏡面邊緣;最多 2 像素線。 |
| 極光綠 | #4ff0a0 | 氧氣極光;保持在其全值的 20% 以下。 |
| H-alpha 玫瑰 | #ff4a6e | 僅用於太陽日珥和色球層。 |
光線與材質
- 單一光源。 太陽是唯一的光源。輝光、邊緣光和閃光必須能由其位置解釋。城市和極光是唯一的發光體,且它們位於夜側。
- 臨邊昏暗 用於任何恆星盤面:
I(mu) = 1 - 0.6*(1 - mu),其中mu = sqrt(1 - r*r);金白相間的核心看起來熾熱,平坦的盤面則像貼紙。 - 大氣是散射,而非輪廓。 受光邊緣是藍色(瑞利散射),光線掠過明暗界線處是金色,當太陽位於行星後方時有前向散射亮度。邊緣很薄:約為行星半徑的 1.5%。
- 夜側 並非黑色:冰冷的月光補光使海洋保持深藍(絕非橄欖色),陸地為中性調的深色,雲層為銀白色,盤面邊緣有青色菲涅爾邊緣,沿海岸線有琥珀色的城市群,以及邊際處一抹微弱的綠色氣輝線。暖金色僅出現在太陽實際照射到的地方。
- 海洋閃光: 太陽反射處的柔和鏡面葉片,朝邊際方向拉長;僅限海洋。
- 金屬: 刷紋鈦金屬是各向異性的。高光沿著刷紋方向延伸,斜面捕捉到一道細薄的香檳色邊緣,接縫處有遮擋。無鏡面鉻效果,無凹凸貼圖噪點。
- 鏡頭: 一條變形鏡頭光斑(水平、細薄、青色調)、二至四個沿畫面中心連線的微弱鬼影。鬼影不透明度低於 4%。使用 ACES 風格的曲線進行色調映射;切勿將高光裁剪為純白色超過數個像素。
構圖
- 地平線位於三分之一處,絕不穿過中心。行星邊際是大弧線(半徑為畫面高度的 1.5–4 倍);整個小地球看起來像個玩具。
- 光事件(太陽升起、鑽石環、第一道光)位於三分之一處,而非正中央,除非鏡頭是關於對稱性(保險庫門、日蝕)。
- 保持星星稀疏(數百顆可見),大小為 1–2 像素,帶有柔和衰減,根據溫度略微偏暖或偏冷。它們在畫面變暗時出現,在畫面變亮時淡出,如同實際曝光。
- 無文字、標誌、抬頭顯示器、星雲壁紙或鏡頭污漬。一次只關注一個主體。
運動詞彙與時機
動詞:密封、解鎖、分開、墜落、升起、攀升、滑翔、吞沒、展開、掙脫、提起。攝影機從不搖晃且極少切換;質量移動緩慢,光移動迅速。
| 拍點 | 典型長度 | 曲線 |
|---|---|---|
| 停留在密封或黑暗畫面上 | 1.0–1.5 秒 | 靜態,僅光線掃過 |
| 機械解鎖 | 0.10–0.20 秒 | 快速緩出,微小安定 |
| 門開啟 / 墜落 | 0.8–1.4 秒 | 緩慢開始,指數加速 |
| 翹曲(條紋) | 1.2–2.0 秒 | 早期達到峰值,平穩衰減至靜止;稀疏,畫面保持大部分黑色 |
| 行星升起 / 軌道滑翔 | 3–6 秒 | 長緩入緩出,絕不線性 |
| 太陽升起或鑽石環 | 0.3–0.6 秒至全閃耀 | 急劇開始,緩慢綻放 |
| 解決與停留 | ≥ 1.5 秒 | 幾乎靜止;讓和弦共鳴 |
運動由 t 以閉合形式計算:位置是創建的速度曲線的積分,絕不逐幀累積。翹曲旅行是 s(t) = integral of v),因此條紋長度為 s(t) - s(t - shutter)。保持條紋少量(每層數十條,而非數百條)、長而柔和,遠層比近層更暗更細;密集均勻的爆發看起來像庫存超空間。
聲音調色盤與混音
- 低頻(30–60 Hz 正弦波,緩慢起伏)承載質量。在約 25 Hz 處對主輸出進行高通濾波(在 JS 中渲染後執行;請參閱音訊主控配方)。
- 金屬: 模態合成。一個 5–10 ms 的帶通濾波噪聲點擊加上 4–6 個非諧波正弦泛音(例如 f0 的 1.00、2.32、3.86、5.40 倍),衰減時間為 0.1–0.8 秒。
- 空氣與旅行: 通過移動帶通濾波器的種子噪聲,與畫面一起聲像定位。無庫存颼颼聲。
- 和聲: 懸浮墊(sus2、sus4)處於張力下;在光事件處解決為大調 add9 和弦。墊音是每個音符 3 個失諧鋸齒波,通過 600–1800 Hz 的低通濾波器。
- 鈴鐺: 加法非諧波泛音(1、2.0、2.76、4.07、5.4),具有 3–8 ms 的起音,衰減時間隨泛音指數縮短。
- 混響: 一個
ConvolverNode,帶有種子立體聲脈衝(2.5–4.5 秒指數衰減、20 ms 預延遲、較暗的尾部)。 - 寂靜是一種提示。 畫面變暗時,淡化聲音;讓光事件擁有第一個響亮時刻。
- 目標: 整合 −18 LUFS,真實峰值 ≤ −1.5 dBFS,尾部在結束前完全衰減 0.3 秒。在程式碼中測量、正規化,然後限制。
技巧配方
管線。 軟體 WebGL 很慢,因此分工:半解析度通道將平滑的 HDR 場景(行星、大氣、日冕)渲染到 RGBA16F 紋理中;全解析度通道對其進行升採樣並添加銳利細節(恆星、城市燈光、耀斑、金屬邊緣),然後進行色調映射和抖色。測量每秒幀數;在 1080p 下保持在 1.5 秒以下。
光線-球體。 解析解,無需對表面進行步進:
vec2 sphere(vec3 ro, vec3 rd, float R) { // t 近點, t 遠點; t < 0 表示未擊中
float b = dot(ro, rd), c = dot(ro, ro) - R*R, h = b*b - c;
if (h < 0.0) return vec2(-1.0);
h = sqrt(h); return vec2(-b - h, -b + h);
}
大氣。 沿殼層內視線的單次散射(8–12 步),光路光學深度近似為 3–4 步。瑞利係數 vec3(5.8, 13.5, 33.1)(按你的行星半徑縮放),米氏散射使用 Henyey–Greenstein 相位 g = 0.76。跳過光線從未進入殼層的像素。
城市燈光。 聚類雜湊噪聲,由陸地和夜晚遮罩:
float night = smoothstep(0.05, -0.15, dot(n, sunDir));
float c = pow(max(fbm3(p*40.0) - 0.45, 0.0)*3.0, 2.0) * land * night;
col += c * vec3(1.0, 0.62, 0.28) * 6.0; // 琥珀色, HDR
恆星,頻帶限制。 每個網格單元一顆恆星,抖動;使用至少 0.8 像素 sigma 的高斯函數繪製,使運動永不頻閃:
vec2 cell = floor(px / 24.0), f = px - (cell + hash22(cell)) * 24.0;
float star = exp(-dot(f, f) / 1.6) * pow(hash12(cell + 7.1), 18.0) * 3.0;
太陽升起耀斑。 所有內容都圍繞太陽的螢幕位置 s 及其可見分數 v(在 JS 中計算)進行解析:
vec2 d = uv - s;
float core = exp(-dot(d, d) * 9000.0), halo = 0.04 / (1.0 + dot(d, d) * 400.0);
float streak = exp(-abs(d.y) * 900.0) * exp(-abs(d.x) * 2.2);
vec3 flare = v * (core * vec3(1.0, .9, .75) * 40.0 + halo * gold + streak * cyan * 2.0);
for (int i = 0; i < 3; i++) { vec2 g = -s * kGhost[i]; /* 在 g 處的柔和圓盤, 2–4 % */ }
刷紋鈦金屬。 各向異性高光,切線沿刷紋方向,加上微弱的頻帶限制條紋(波長 ≥ 3 像素):
float TH = dot(T, H);
float aniso = pow(sqrt(max(1.0 - TH*TH, 0.0)), 60.0);
float grain = 0.92 + 0.08 * noise(vec2(r * 300.0, angle * 3.0));
vec3 metal = base * (0.25 + 0.75 * diffuse) * grain + champagne * aniso;
日蝕。 月球略大於太陽(1.04–1.08)。給月球邊際一些噪點,使貝利珠和鑽石環自然出現在接近接觸點處。日冕:亮度 pow(r, -3) 乘以來自噪聲的流線(角度、log r 空間),加上來自高角頻率、低徑向頻率噪聲的細絲。
將邊際輪廓編寫為整數頻率正弦波和包裹高斯凹口的和,然後將其作為 JS 字串和 GLSL 字串輸出。JS 隨後可以逐幀積分可見光球層(每個以太陽為中心的光線進行一次二分法,約 700 條光線),從而得到可見分數、眩光的光珠質心以及樂譜的確切接觸時間。光珠眩光需要分數的對數映射,例如 log(1 + f*1e6) / log(1 + 1e6)。從粗糙 mip 繪製的寬眩光會在 HDR 光源上顯示階梯狀,因此使用四個半紋素偏移的雙線性取樣來模糊每個層級。
音訊主控(確定性)。 在 startRendering() 之後,在 JS 中測量整合 LUFS(BS.1770 K 加權和閘控),縮放到 −18,然後在 −1.5 dBFS 處對 4 倍過採樣的峰值運行一個前瞻峰值限制器。使用 mulberry32 為每個噪聲緩衝區和脈衝提供種子。
在 headless Chromium 中,這些會使位元精確的重複測試失敗:通過主 BiquadFilterNode 或 DynamicsCompressorNode 的立體聲信號,以及任何具有三個或更多輸入的節點,因為求和順序會變化一個 ULP。保持主匯流排節點空閒(增益到目標)。在 JS 中渲染後執行高通濾波和匯流排壓縮。將混響的高通濾波烘焙到其脈衝中。透過 2 輸入增益鏈接每個扇入,因為 a + b 是精確且可交換的。
function mulberry32(a){return()=>{a|=0;a=a+0x6D2B79F5|0;let t=Math.imul(a^a>>>15,1|a);
t=t+Math.imul(t^t>>>7,61|t)^t;return((t^t>>>14)>>>0)/4294967296;};}
確定性檢查清單
renderFrame(t)僅從t設定每個 uniform;在渲染模式下無Date、performance.now、Math.random或逐幀累積。- 僅使用種子雜湊和 PRNG;當圖片和聲音必須一致時,使用相同的種子。
- 向後搜尋可重現相同的像素;在後期影格後測試 t = 0。
preserveDrawingBuffer: true、antialias: false;在renderFrame結束時調用gl.finish()。- 預覽模式使用
requestAnimationFrame循環;?render=1本身不繪製任何內容。 renderAudio每次調用返回相同的緩衝區,跨兩次渲染逐樣本比較;響度和真實峰值是被測量的,而非猜測的。- 檢查光事件、之前一影格和最後影格的靜止圖像;逐影格檢查時序。
避免
- 卡通輪廓、行星周圍的發光輪廓、飽和的紫色星雲、帶有六邊形環的鏡頭光暈預設。
- 旋轉的地球儀、快速的攝影機移動、抖動或無物理原因的運動線。
- 將高光裁剪為純白色、提亮的黑色、條帶(在輸出前添加次 LSB 抖色)。
- 逐幀全螢幕顆粒或 1 像素閃爍;它們會頻閃並使 H.264 臃腫。
- 每個動作的音效、廉價的颼颼聲、無處可去的上升音、緩衝區邊緣的點擊聲、被影片結束切斷的混響尾聲。
- 除非簡報要求,否則不要使用文字、標誌或介面元素。