Communitygithub.com

pisakhov/x-motion-prism

與核心 x-motion 技能搭配使用,當影片應專注於光、玻璃與色彩在靜止中的表現(折射、色散、焦散、透鏡),在明亮的紙白工作室中進行確定性渲染,並搭配合成的玻璃般配樂。

x-motion-prism 是什麼?

Prism 是為「x-motion」核心方法設計的主題,專注於在明亮、潔白的攝影棚環境中,以高藝術性和物理精確度,創作關於光、玻璃和色彩的簡短影片。此主題的核心敘事圍繞單一的「英雄光學現象」(如色散或焦散),並運用嚴格的調色盤(消色差的紙、石、石墨,只在光譜分離處才顯色)、精確的物理渲染(包含柯西色散、解析焦散與色散折射),以及全確定性的製作流程。其輸出為 9 到 10 秒的影片,搭配由玻璃、空氣與水聲合成的同步配樂,所有參數皆從時間函數驅動,無隨機性,且完全在瀏覽器中渲染。主要支援平台為基於 Web 的環境(如 Claude Code 或 Cursor 可使用 x-motion 方法),強調數學驅動與完美可重複的像素級與音頻級輸出。

相容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/pisakhov/x-motion/tree/HEAD/skills/x-motion-prism

在你喜歡的 AI 中提問

開啟一個已預先載入此 Agent Skill 的新對話。

說明文件

X Motion:稜鏡

Prism 是核心 x-motion 方法的主題。請遵循該方法(簡介、論文、分鏡、動態腳本、製作、限定評論)。此檔案增加了使主題可識別並保持其真實性的藝術指導、物理和聲音。

視覺論文

讓一種光學現象感覺精確且靜默地神奇,透過像拍攝靜物般在淺色攝影棚中捕捉它,使觀者注意到光實際上的行為。

  • 每部影片一個英雄現象。 色散、焦散、透鏡成像、全內反射、菲涅爾邊緣。其他一切都只是讓它降落的平靜表面。
  • 物理決定色彩的歸屬。 世界是消色差的:紙張、石頭、石墨。光譜色僅在波長分離處出現(離開稜鏡的光扇、透鏡的邊緣、焦散的邊緣),而非其他地方。
  • 亮度即是情緒。 這與黑暗空間主題相反。陰影是柔和的石墨色,絕非黑色;亮部是光,絕非霓虹。
  • 相機是腳架。 鎖定或幾乎無法察覺的推移。現象在動;觀察者不動。

調色盤

角色十六進位碼用途
紙張#f2efe9主導表面,環境日光
陰影中的紙張#d9d4cb主光源區域外的部分
淺色石頭#e6e1d8地板、水池、基座(以低頻噪聲 ±3% 變異)
石墨#5d5b57印刷線條、接觸陰影(透明度 20–60%)
深石墨#3a3936允許的最暗值,僅用於接觸摺痕
水色調#d8e6e4在石頭上方以「相乘」模式疊加,用於淺層清水
光譜計算得出僅來自波長至 RGB 的函數,絕非手選的彩虹

線上性光中工作,累加光能量,然後進行色調映射並一次轉換為 sRGB。在明亮背景上的疊加光譜色會變淡,因此需在色彩需呈現飽和處局部降低背景亮度(在英雄現象周圍創造柔和陰影區域,約 45–60% 線性),並保持畫面其餘部分通透。

光線與材質

  • 主光: 一個來自左上方、與畫面軸線約 30–45° 的柔和日光光源。陰影長、柔和且略帶暖灰色。
  • 玻璃: 清澈、無色、無瑕。其存在僅透過四件事體現:背後物體的折射、一條細菲涅爾邊緣、一個柔和窗戶反射,以及它所投射的焦散或光譜光。無倒角光暈、無色調玻璃、無綻放光暈。
  • 折射率: Cauchy 色散公式,n(λ) = A + B/λ²,λ 單位為 µm。皇冠玻璃:A = 1.5046, B = 0.0042。當色散需要在螢幕上可讀時,可將 B 誇大約 3 倍,並在你的筆記中說明。
  • 紙張與石頭: 霧面,極低對比紋理(亮度變化 2–4%),靜態於時間中。精細印刷線條為 1.2–2 px 的石墨色,帶有柔和衰減。
  • 接觸: 每個接觸表面的物體都會獲得一個緊繃、更暗的接觸陰影,加上一個寬廣柔和的陰影。這正是讓玻璃感覺穩固而非漂浮的關鍵。

構圖

  • 寬闊的負空間:英雄現象約占畫面三分之一;其餘為帶有柔和光線漸層的紙張或石頭。
  • 將事件置於三分線或黃金點上,除非影片主題是對稱,否則絕不置中。
  • 用光線引導視線:光束、滾動方向或漣漪應朝向回報發生的地方。
  • 保持畫面邊緣寧靜且略暗(來自光源的 6–10% 暗角,非黑色環)。
  • 無文字、UI、標誌或裝飾性粒子。若現象需要比例參考,請使用印刷網格、石頭接縫或陰影。

運動詞彙與節奏

動詞:進入、彎曲、展開、掃掠、對焦、漣漪、沉降。 移動的名詞:光、水、單一物體。不要同時移動相機和主體。

拍點佔 9–10 秒影片的典型比例行為
靜止10–15%空的、點亮的場景。讓觀者閱讀表面。
抵達15–20%光線或物體沿著清晰路徑以減速緩動進入。
現象35–45%英雄效果緩慢發展變化(旋轉幾度、滾動、漣漪)。
沉降20–25%運動以物理方式衰減(摩擦、阻尼、波浪擴散)並保持。
釋放5–8%光線變暗或影像靜止,以便循環和音頻尾聲能閉合。
  • 使用物理閉合形式的運動:滾動用恆定減速,沉降用阻尼餘弦,擴散環用 1/sqrt(r) 振幅,旋轉用緩動角度。
  • 當你動畫化光束頭時,光在玻璃內的速度明顯慢於空氣中(v_glass = v_air / n)。這是一個觀者能感受到的微小真實。
  • 偏好一個長手勢勝過數個短手勢。一整圈太多;4–10° 就足以讓光譜掃掠。

聲音調色板與混音

聲音是玻璃、空氣和水,經過調音。它應該感覺像一個有著堅硬、清潔表面的房間。

  • 玻璃泛音: 模態合成,搭配少量非諧波泛音(對於敲擊玻璃,比例接近 1, 2.32, 4.25, 6.63),每個都有自己的指數衰減;較高泛音消失得更快。
  • 手指擦玻璃聲: 一兩個正弦波,帶有 0.3–0.6 秒的緩慢膨脹、4–5 Hz 的顫音(±0.15%)以及一絲在同音高上的帶通濾波噪聲。
  • 空氣聲: 帶粉紅色種子的噪聲,通過帶通濾波器(300–2500 Hz),非常低,緩慢呼吸。這是房間的聲音,不是風聲。
  • 水聲: 泡泡「噗通」聲是頻率在 30–80 毫秒內指數上升約 30–60% 的正弦波;柔和沖洗聲是低通濾波噪聲。
  • 和聲: 選擇一個調性並保持(開放五度、附加九度、利地安調式色彩)。將現象映射到音高:光譜位置映射到音階音級,速度映射到濾波器截止頻率,停止映射到解決的鍾聲。
  • 空間: 一個使用種子生成的合成卷積混響(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 中計算的統一變數傳遞。將畫面分割成幾個小型單一用途的通道(地板、半解析度的光場進入 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.));
}

在明亮背景上,紫光端呈現為淡薰衣草色;這是誠實的,因此應給予它一個更暗的局部區域,而非增強它。

每個波長的折射。 使用不同折射率(紅、綠、藍或更多)追蹤同一條光線兩三次。結果一致處,你得到清晰的中性細節;結果分歧處,你得到正好物理預測處的色差邊緣。

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 是深度除以折射率。解析計算 Hessian 矩陣(正弦波和徑向環包兩者皆有閉合形式),用 1 / sqrt(det² + ε²) 軟化奇異點,並以三個稍微不同的 d 值評估它,以獲得薄光譜邊緣。

平面上的光線。 掠過紙張的光束是一個沿其軸線的 1D 高斯分佈,exp(-(dist/w)²),加上一個更寬、更淡的光暈。光束頭沿著路徑以緩動距離前進;用一個短 smoothstep 裁切,而非硬邊緣。

帶限印刷。 根據到最近線條的距離對上螢幕空間足跡(命中點的 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));
}

玻璃需要一些暗的東西來折射。 在白色攝影棚中,完美球體會變成乳白色。為環境提供接近地平線的灰色牆壁、一個緊湊的柔光箱和一面黑色旗幟;球體內翻轉的地平線和窗戶便描繪出其形狀。計算所有路徑而不分支,以使 fwidth 保持有效,並將解析覆蓋率(光線到中心距離除以半徑,以像素為單位)輸出為 alpha。

色調與完成。 指數肩部 1 - exp(-1.85 x) 使紙張保持在 #f2efe9 附近,同時焦散峰值柔和滾降;然後 sRGB。每個通道的肩部會將明亮光譜帶漂白成柔和色調,因此對於有色光,約一半量地混合到色調保持曲線(對最大通道進行色調映射並縮放),由色度門控,使紙張不受影響。完全保持色調,或銳化頻帶顏色,會將橙色、黃色和青色壓平為平坦的紅、綠和藍色條帶。數值檢查光扇:對其進行橫向採樣,確認色調僅上升一次,從紅色(約 10°)到紫色(約 270°),沒有環繞。僅添加靜態的子-最低有效位抖動(±0.6/255)以打破蒼白漸層中的條帶;永遠不要逐幀動畫化它。

速度。 SwiftShader 是軟體渲染,著色器中的每一條指令都要付出代價,包括沒有像素會取用的分支。保持每個通道單一用途,以半解析度渲染柔和光場,並將昂貴的通道(玻璃、稜鏡內部)裁剪到物體的投影邊界框,使用 SRC_ALPHA, ONE_MINUS_SRC_ALPHA 與地板混合。在打磨前,測量 1920×1080 解析度下每秒幀數;最多使用 5 個八度的不規則雜訊函數。

確定性音頻圖。 Chromium 以未指定的順序將三個或更多連接加總到一個 AudioNode 中,因此兩次渲染會有約 1e-6 的差異,並導致字節檢查失敗。在 JavaScript 中合成每個聲音到一個立體聲 Float32 混合中(相位累加正弦波、基於種子噪聲的 RBJ 雙二階濾波器、樣本精確包絡),然後圖形僅用於一個單一源信號進入乾增益和一個卷積器,兩者再進入一個高通濾波器(兩個輸入可交換),然後是一個溫和壓縮器(約 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 倍過採樣峰值),應用一個增益以達到目標響度,並在峰值限制需要時應用較低增益。確定性且簡單。

確定性渲染核對清單

  • window.motion 宣告寬度、高度、時長、幀率和在最美麗幀上的海報時間。
  • renderFrame(t) 僅從 t 設定每個統一變數;在渲染模式中無 Date、performance.now、Math.random、計時器或累積狀態。
  • 向後然後向前搜尋能產生相同的像素;第一幀和最後一幀捕獲都是有效的。
  • 預覽模式(無 ?render=1)以 requestAnimationFrame 循環;點擊播放相同的渲染音頻緩衝區,並保持同步。
  • renderAudio 在 JavaScript 中混合聲音,然後在 OfflineAudioContext 中透過一個使用種子生成的卷積器渲染一個源信號;兩次調用返回位元組相同的樣本(無節點有三個或更多輸入)。
  • 提示映射表是一個由圖片和聲音共享的時間表(撞擊、停止、釋放),且混響尾巴在最後 0.3 秒低於 -45 dB。
  • 無網路、字體、圖片或樣本;每個紋理和聲音都是程式生成的。

避免

  • 橫跨畫面的彩虹漸層、彩虹文字、彩虹色「全息」表面。
  • 霓虹色、紫藍色「AI」漸層、黑色背景、鏡頭光暈和變形鏡頭條紋。
  • 光澤的 3D 渲染玻璃:厚亮倒角、色調玻璃、HDRI 鍍鉻反射、萬物皆綻放。
  • 無接觸陰影的浮動物體;非來自物理原因的顏色。
  • 相機繞行、快速剪輯、粒子、閃光、咻聲和上升音。
  • 逐幀隨機雜訊和在 H.264 壓縮後閃爍的單像素線條。
  • 削波的聲音、與調性衝突的和弦疊加、在結尾被截斷的混響尾巴。

Individual skills in this repo

This repo contains 3 individual skills — each has its own dedicated page.

相關技能