Communitygithub.com

pisakhov/x-motion-orbit

与核心 x-motion 技能配合使用,为短片赋予轨道外观:物理光照下的太空、行星、日食、钛金属质感,以及静谧的合成配乐。

x-motion-orbit 是什么?

**pisakhov/x-motion-orbit** 是一个 AI 辅助创意技能,专为生成具有高度一致“轨道美学”的短片而设计。它并非独立的替代品,而是对 [x-motion](https://github.com/pisakhov/x-motion) 核心工作流程的扩展。使用此技能时,AI 会先生成影片的简报、剧情梗概、故事板并进行批评反馈,然后利用当前文件中的艺术指导原则和具体渲染配方来指导后续的视觉与音频生成。 该技能特别要求渲染 8-12 秒、1920×1080 分辨率、30fps 的短片,并通过无头 Chromium 浏览器和软件 WebGL(基于 `renderFrame(t)` 函数)进行确定性渲染。其视觉体系强调“黑暗就是本色,光是唯一事件”,60-80% 的画面保持纯黑,主体往往是巨大的行星、卫星或机械门,配以薄而明亮的边缘。运动设计注重稳定与缓慢的质感,光线则快速移动;相机从不摇晃,很少切换。 在技术实现上,Orbit 技能提供了一套完整的确定性渲染和工作流指南,覆盖了线性 HDR 调色板、单光源(太阳)散射模拟(如瑞利散射、米氏散射)、大气辉光、钛金属各向异性着色、日食渲染、星点、城市灯光、镜头光晕(包括变形宽银幕眩光)等。此外,它还包含一套完全在 JavaScript 中实现的、确定性的音频设计配方,通过模态合成、噪声和铺底音色来营造太空、金属、空气和静谧感,并包含了精确的响度(-18 LUFS)和真峰值(≤ -1.5 dBFS)控制。 此技能要求在整个渲染管线(从画面到音频)中保持严格的确定性,禁止使用系统时间或随机函数,所有随机性必须源自带种子的伪随机数生成器。它支持并强烈推荐在 AI 编码助手(如 Claude Code、Cursor、Codex)环境中使用,以快速迭代和精确控制创意输出。

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

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

X Motion · 轨道

Orbit 扩展了 x-motion;它不会取代它。先运行核心方法(简报、剧情梗概、故事板、批评),再使用本文件作为艺术指导和配方。本技能专为 8-12 秒、1920×1080、30 fps 的影片编写,这些影片通过 renderFrame(t) 在无头 Chromium 浏览器中结合软件 WebGL 进行确定性渲染。

视觉理念

太空是黑色的,光则是事件。只有一个光源(太阳)以及它所触及的材料:大气层、海洋、云层、金属。每一部影片都围绕着光到达、越过边缘或挣脱束缚的单一瞬间构建。

静默的自信胜过宏大的场面。画面大部分是纯正的黑色;主体是一个巨大的、缓慢移动的物体(行星、卫星、保险库门)和一道薄而明亮的边缘。如果一帧画面看起来像壁纸或游戏菜单,那就移除元素,直到它看起来像由一台耐心的相机拍摄的照片。

调色板

在线性 HDR 空间中工作,最后再进行色调映射;以下是眼睛应该落脚的、以显示为参考的目标色值。

角色十六进制色值用途
纯黑色#000000占据大多数帧的 60-80%。切勿用雾霾效果将其提亮。
虚空海军蓝#050b18远离任何光源的深空渐变。
深海军蓝#0b1a33夜间海洋、阴影中的金属、提亮后的黑暗天空。
瑞利蓝#2f6fd8大气层在白天的本体颜色。
大气青色#8fd3ff菲涅尔边缘光,薄薄的边缘线。
日出金色#ffc46b太阳核心的光晕衰减、晨昏线、云层顶部的第一缕光。
余烬琥珀色#ffa448夜半球的城市灯光(钠灯)。
珍珠母贝色#ece8de日冕、星星、铃铛般的高光。
钛金属色#8a8f96拉丝金属的本体颜色。
镍色#c3c6c8金属高光、倒角平面。
香槟色#e9d4a6金属上的暖色镜面反射边缘;最多 2 个像素宽。
极光绿#4ff0a0氧气极光;保持在其满值亮度的 20% 以下。
H-α 玫瑰色#ff4a6e仅用于太阳耀斑和色球层。

光照与材质

  • 单一光源。 太阳是唯一的光源。辉光、边缘光和闪光必须由其位置来解释。城市和极光是唯一的自发光体,且它们位于夜半球。
  • 任何恒星盘面的临边昏暗:I(mu) = 1 - 0.6*(1 - mu),其中 mu = sqrt(1 - r*r);从金色过渡到白色的核心看起来炽热,而扁平的圆盘看起来像贴纸。
  • 大气层是散射效果,不是描边。 照亮边缘呈现蓝色(瑞利散射),光线掠过晨昏线处呈现金色,当太阳位于行星后方时有前向散射的亮度。边缘很薄:约为行星半径的 1.5%。
  • 夜半球 并非全黑:冷却的月光填充色使海洋保持深蓝(绝不为橄榄色),陆地呈较暗的中性色调,云层为银白色,圆盘边缘有青色菲涅尔边缘光,沿海岸线分布着琥珀色的城市集群,以及边缘处淡淡的绿色气辉线。暖金色仅出现在太阳实际照射到的地方。
  • 海洋反光:太阳反射处出现柔和的镜面光斑,向边缘方向拉长;仅限海洋。
  • 金属:拉丝钛合金是各向异性的。高光沿着拉丝方向拉伸,倒角捕捉到一条薄薄的香槟色边缘,接缝处有环境光遮蔽。没有铬镜面效果,没有凹凸贴图噪声。
  • 镜头:一个变形宽银幕眩光(水平方向,细长,青色色调),沿着穿过画面中心的线有两到四个微弱的鬼影。鬼影的不透明度低于 4%。使用 ACES 风格的曲线进行色调映射;切勿将高光裁剪为平坦的白色超过几个像素。

构图

  • 地平线位于三分之一线上,绝不穿过中心。行星边缘是大弧线(半径 1.5-4 倍画面高度);整个小星球看起来像个玩具。
  • 光线事件(太阳升起、钻石环、第一缕光)落于三分之一线上,而不是正中心,除非镜头是关于对称性的(如保险库门、日食)。
  • 保持星星稀疏(可见数百颗),大小为 1-2 像素,带有柔和的衰减,根据温度略微偏暖或偏冷。当画面变暗时它们显现,变亮时则消失,如同曝光效果。
  • 没有文字、标志、HUD、星云壁纸或镜头污垢。一次只聚焦一个主体。

运动词汇与节奏

动词:封闭、解锁、分开、坠落、升起、达到顶点、滑翔、吞没、展开、挣脱、提升。相机从不摇晃,很少有切换;主体移动缓慢,光线移动迅速。

节拍典型时长曲线
停留在封闭或黑暗的画面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 毫秒的带通噪声喀哒声加上 4-6 个非谐波正弦泛音(例如基频的 1.00、2.32、3.86、5.40 倍),衰减时间为 0.1-0.8 秒。
  • 空气与旅行:通过移动带通滤波的种子噪声,根据画面进行声像定位。没有现成的呼啸声。
  • 和弦:悬置和弦(sus2、sus4)营造紧张感;在光线事件时解决为大调加九和弦。铺底音色每个音符由 3 个失谐锯齿波组成,通过 600-1800 Hz 的低通滤波器。
  • 铃声:加性非谐波泛音(1、2.0、2.76、4.07、5.4),起音时间为 3-8 毫秒,衰减时间随泛音指数增加而缩短。
  • 混响:一个 ConvolverNode,带有种子的立体声脉冲响应(2.5-4.5 秒指数衰减,20 毫秒预延迟,更暗的尾音)。
  • 静默本身也是一种提示。 当画面变暗时弱化声音;让光线事件占据第一个响亮时刻。
  • 目标:综合响度 -18 LUFS,真峰值 ≤ -1.5 dBFS,尾音在结束前 0.3 秒完全衰减。在代码中测量、归一化,然后限制。

技术配方

管线。 软件 WebGL 速度较慢,因此需分工协作:半分辨率通道将平滑的 HDR 场景(行星、大气、日冕)渲染到 RGBA16F 纹理中;全分辨率通道对其进行升采样并添加锐利细节(星星、城市灯光、耀斑、金属边缘),然后进行色调映射和抖动。测量每帧的秒数;在 1080p 下保持低于 1.5 秒。

射线-球体相交。 解析计算,无需表面步进:

vec2 sphere(vec3 ro, vec3 rd, float R) {           // t near, t far; 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 中测量综合响度(BS.1770 K-weighting 和 gating),缩放至 -18,然后在 4 倍过采样的峰值上运行一个前视峰值限制器,阈值为 -1.5 dBFS。使用 mulberry32 为每个噪声缓冲区和脉冲响应设定种子。

在无头 Chromium 中,以下情况会破坏逐比特重复测试:通过主 BiquadFilterNode 或 DynamicsCompressorNode 的立体声信号,以及任何具有三个或更多输入的节点,因为求和顺序会变化 1 个 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 或逐帧累积。
  • 仅使用带种子的哈希和伪随机数生成器;当画面和声音需要保持一致时,使用相同的种子。
  • 向后查找会产生相同的像素;在渲染较晚的帧后测试 t = 0。
  • preserveDrawingBuffer: true, antialias: false;在 renderFrame 结束时调用 gl.finish()。
  • 预览模式使用 requestAnimationFrame 循环;?render=1 本身不绘制任何内容。
  • renderAudio 每次调用返回相同的缓冲区,在两次渲染之间逐样本比较;响度和真峰值是测量的,而非猜测的。
  • 检查光线事件、它前一帧以及最后一帧的静止图像;逐帧检查时间。

避免

  • 卡通轮廓、行星周围发光的描边、饱和的紫色星云、带有六边形环的镜头光晕预设。
  • 旋转的球体、快速的相机移动、摇晃,或没有物理原因的速度线。
  • 将高光裁剪为平坦的白色、提升黑色、条带色阶(在输出前添加低于 LSB 的抖动)。
  • 逐帧的全屏颗粒或 1 像素闪光;它们会产生频闪并增加 H.264 码率。
  • 每个动作都有音效、俗气的呼啸声、没有进展的上升音、缓冲区边缘的喀哒声、在影片结束时被切断的混响尾音。
  • 文字、标志或界面装饰,除非简报要求。

Individual skills in this repo

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

相关技能