X Motion · Orbit
Orbit extiende x-motion; no lo reemplaza. Ejecuta el método central (resumen, tesis, guion gráfico, crítica) y usa este archivo para la dirección artística y las recetas. Fue escrito para cortometrajes de 8–12 segundos, 1920×1080, 30 fps renderizados de forma determinista desde renderFrame(t) en Chromium sin interfaz gráfica con WebGL por software.
Tesis visual
El espacio es negro, y la luz es el evento. Una sola fuente (el sol) y los materiales que toca: atmósfera, océano, nube, metal. Cada película se construye alrededor del momento único en que la luz llega, cruza un limbo o se libera.
Confianza tranquila por encima del espectáculo. El encuadre es mayormente negro verdadero; el sujeto es una masa grande y lenta (un planeta, una luna, una puerta de bóveda) y un borde brillante y delgado. Si un fotograma parece un fondo de pantalla o un menú de juego, elimina cosas hasta que parezca una fotografía tomada por una cámara paciente.
Paleta
Trabaja en HDR lineal y aplica tonemapping al final; estos son objetivos referidos a la pantalla para lo que el ojo debe percibir.
| Rol | Hex | Uso |
|---|---|---|
| Negro verdadero | #000000 | 60–80 % de la mayoría de los fotogramas. Nunca lo eleves con neblina. |
| Azul marino vacío | #050b18 | Gradiente de espacio profundo, lejos de cualquier luz. |
| Azul marino profundo | #0b1a33 | Océano nocturno, metal sombreado, cielo oscuro después de un "levantamiento". |
| Azul Rayleigh | #2f6fd8 | Cuerpo de la atmósfera en el lado diurno. |
| Cian atmosférico | #8fd3ff | Borde Fresnel, línea delgada del limbo. |
| Oro amanecer | #ffc46b | Caída del núcleo solar, terminador, primera luz en las cimas de las nubes. |
| Ámbar ascua | #ffa448 | Luces de la ciudad (sodio) en el lado nocturno. |
| Perla corona | #ece8de | Corona, estrellas, reflejos tipo campana. |
| Titanio | #8a8f96 | Cuerpo de metal cepillado. |
| Níquel | #c3c6c8 | Reflejos metálicos, superficies planas de biseles. |
| Champán | #e9d4a6 | Borde especular cálido sobre metal; como máximo una línea de 2 píxeles. |
| Verde aurora | #4ff0a0 | Aurora de oxígeno; mantén por debajo del 20 % de su valor completo. |
| Rosa H-alfa | #ff4a6e | Solo para protuberancias solares y cromosfera. |
Luz y material
- Una luz. El sol es la única fuente. Los resplandores, bordes y destellos deben explicarse por su posición. Las ciudades y las auroras son los únicos emisores, y viven en el lado nocturno.
- Oscurecimiento del limbo para cualquier disco estelar:
I(mu) = 1 - 0.6*(1 - mu)conmu = sqrt(1 - r*r); un núcleo de oro a blanco se lee como caliente, un disco plano se lee como una pegatina. - La atmósfera es dispersión, no un trazo. Azul (Rayleigh) en el limbo iluminado, oro donde la luz roza el terminador, brillo dispersado hacia adelante cuando el sol está detrás del planeta. El borde es delgado: aproximadamente el 1.5 % del radio del planeta.
- El lado nocturno no es negro: un relleno de luz lunar fría mantiene el océano azul profundo (nunca verde oliva), la tierra un tono neutro más oscuro, las nubes blanco plateado, un borde Fresnel cian en el borde del disco, grupos de ciudades ámbar siguiendo las costas, y una tenue línea de brillo verde atmosférico en el limbo. El oro cálido aparece solo donde el sol realmente alcanza.
- Brillo oceánico: un lóbulo especular suave donde se refleja el sol, alargado hacia el limbo; solo océano.
- Metal: el titanio cepillado es anisótropo. Los reflejos se extienden a lo largo de la dirección del cepillado, los biseles capturan un borde delgado de champán, las uniones tienen oclusión. Sin espejo cromado, sin ruido de mapa de relieve.
- Lente: una raya anamórfica (horizontal, delgada, teñida de cian), dos a cuatro fantasmas tenues a lo largo de la línea que pasa por el centro del encuadre. Opacidad del fantasma menor al 4 %. Aplica tonemapping con una curva de estilo ACES; nunca recortes un destello a blanco plano por más de unos pocos píxeles.
Composición
- Los horizontes se sitúan en un tercio, nunca en el centro. Los limbos planetarios son grandes arcos (radio 1.5–4 alturas de encuadre); un globo pequeño entero parece un juguete.
- El evento de luz (cresta solar, anillo de diamante, primera luz) cae en un tercio, no en el centro, a menos que la toma trate de simetría (una puerta de bóveda, un eclipse).
- Mantén las estrellas escasas (unos pocos cientos visibles), de tamaño 1–2 píxeles con caída suave, ligeramente cálidas o frías según la temperatura. Aparecen cuando el encuadre se oscurece y se desvanecen cuando se ilumina, como lo haría la exposición.
- Sin texto, logotipos, HUD, fondos de nebulo sa ni suciedad de lente. Un sujeto a la vez.
Vocabulario de movimiento y temporización
Verbos: sellar, desenganchar, separar, caer, elevarse, crester, deslizarse, tragar, desplegar, liberarse, levantar. La cámara nunca tiembla y rara vez corta; la masa se mueve lentamente, la luz se mueve rápido.
| Ritmo | Duración típica | Curva |
|---|---|---|
| Pausa en un encuadre sellado u oscuro | 1.0–1.5 s | estática, solo barrido de luz |
| Desenganche mecánico | 0.10–0.20 s | ease-out rápido, pequeño asentamiento |
| Puertas separándose / caída | 0.8–1.4 s | inicio lento, aceleración exponencial |
| Curvatura (rayas) | 1.2–2.0 s | pico temprano, decae suavemente hasta la inmovilidad; escaso, el encuadre permanece mayormente negro |
| Elevación planetaria / deslizamiento orbital | 3–6 s | ease-in-out largo, nunca lineal |
| Cresta solar o anillo de diamante | 0.3–0.6 s hasta el destello completo | inicio brusco, floración lenta |
| Resolución y pausa | ≥ 1.5 s | casi quieto; deja que el acorde resuene |
El movimiento se calcula en forma cerrada a partir de t: las posiciones son integrales de curvas de velocidad creadas, nunca acumuladas por fotograma. El viaje por curvatura es s(t) = integral de v, por lo que la longitud de la raya es s(t) - s(t - obturador). Mantén las rayas pocas (decenas por capa, no cientos), largas y suaves, con capas lejanas más tenues y delgadas que las cercanas; una ráfaga densa y uniforme se lee como hiperespacio genérico.
Paleta de sonido y mezcla
- Sub (senos de 30–60 Hz con oleajes lentos) transporta la masa. Aplica un filtro paso alto al máster a aproximadamente 25 Hz (en JS después del renderizado; consulta la receta de máster de audio).
- Metal: síntesis modal. Un clic de ruido con paso de banda de 5–10 ms más 4–6 parciales senoidales inarmónicas (por ejemplo 1.00, 2.32, 3.86, 5.40 veces f0) con decaimientos de 0.1–0.8 s.
- Aire y viaje: ruido sembrado a través de un paso de banda móvil, paneado con la imagen. Sin whooshes genéricos.
- Armonía: pads suspendidos (sus2, sus4) bajo tensión; resuelve a un add9 mayor en el evento de luz. Los pads son 3 sierras desafinadas por nota a través de un paso bajo de 600–1800 Hz.
- Campanas: parciales inarmónicos aditivos (1, 2.0, 2.76, 4.07, 5.4) con un ataque de 3–8 ms y decaimientos que se acortan con el índice del parcial.
- Reverberación: un
ConvolverNodecon un impulso estéreo sembrado (decaimiento exponencial de 2.5–4.5 s, pre-retardo de 20 ms, cola más oscura). - El silencio es una señal. Adelgaza el sonido cuando la imagen se oscurece; deja que el evento de luz posea el primer momento fuerte.
- Objetivos: integrado −18 LUFS, pico verdadero ≤ −1.5 dBFS, cola completamente decaída 0.3 s antes del final. Mide en código, normaliza, luego limita.
Recetas técnicas
Pipeline. WebGL por software es lento, así que divide el trabajo: un pase a media resolución renderiza la escena HDR suave (planeta, atmósfera, corona) en una textura RGBA16F; un pase a resolución completa la sobremuestrea y añade detalles nítidos (estrellas, luces de ciudad, destellos, bordes metálicos), luego aplica tonemapping y dithering. Mide segundos por fotograma; mantente por debajo de 1.5 s a 1080p.
Ray–esfera. Analítico, sin marching para la superficie:
vec2 sphere(vec3 ro, vec3 rd, float R) { // t cercano, t lejano; t < 0 significa fallo
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);
}
Atmósfera. Dispersión única a lo largo del rayo de visión dentro de la capa (8–12 pasos), con la profundidad óptica de la trayectoria de la luz aproximada en 3–4 pasos. Coeficientes Rayleigh vec3(5.8, 13.5, 33.1) (escalados al radio de tu planeta), Mie con una fase Henyey–Greenstein g = 0.76. Salta píxeles cuyo rayo nunca entra en la capa.
Luces de ciudad. Ruido hash de conglomerados, enmascarado por tierra y por noche:
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; // ámbar, HDR
Estrellas, con límite de banda. Una estrella por celda de cuadrícula, con desplazamiento; dibuja con una gaussiana de al menos 0.8 píxeles sigma, para que el movimiento nunca estrobe:
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;
Destello de cresta solar. Todo es analítico alrededor de la posición en pantalla del sol s y su fracción visible v (calculada en 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]; /* disco suave en g, 2–4 % */ }
Titanio cepillado. Reflejo anisótropo con la tangente a lo largo de la dirección del cepillado, más rayas tenues con límite de banda (longitud de onda ≥ 3 píxeles):
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;
Eclipse. Luna ligeramente más grande que el sol (1.04–1.08). Dale al limbo lunar un poco de ruido para que las cuentas de Baily y un anillo de diamante aparezcan naturalmente cerca del contacto. Corona: brillo pow(r, -3) veces serpentinas desde ruido en (ángulo, log r), más filamentos finos de ruido de alta frecuencia angular y baja frecuencia radial.
Escribe el perfil del limbo una vez como una suma de senos de frecuencia entera y muescas gaussianas envueltas, luego emítelo tanto como JS como una cadena GLSL. JS puede entonces integrar la fotosfera visible por fotograma (una bisección por rayo centrado en el sol, unos 700 rayos), lo que da la fracción visible, el centroide de las cuentas para el resplandor y los tiempos de contacto exactos para la partitura. El resplandor de las cuentas necesita un mapeo logarítmico de la fracción, como log(1 + f*1e6) / log(1 + 1e6). El resplandor amplio dibujado desde mipmaps gruesos muestra escalones en fuentes HDR, así que difumina cada nivel con cuatro muestras bilineales en desplazamientos de medio texel.
Máster de audio (determinista). Después de startRendering(), mide los LUFS integrados (ponderación K BS.1770 y compuerta) en JS, escala a −18, luego ejecuta un limitador de pico con anticipación en picos sobremuestreados 4× a −1.5 dBFS. Siembra cada búfer de ruido e impulso con mulberry32.
En Chromium sin interfaz gráfica, estos fallan en una prueba de repetición exacta a nivel de bits: una señal estéreo a través de un BiquadFilterNode o DynamicsCompressorNode maestro, y cualquier nodo con tres o más entradas, porque el orden de suma varía en un ULP. Mantén el bus maestro libre de nodos (ganancia a destino). Ejecuta el paso alto y la compresión del bus en JS después del renderizado. Hornea el paso alto de una reverberación en su impulso. Encadena cada fan-in a través de ganancias de 2 entradas, ya que a + b es exacto y conmutativo.
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;};}
Lista de verificación determinista
renderFrame(t)establece cada uniforme solo a partir det; sinDate,performance.now,Math.randomni acumulación por fotograma en modo de renderizado.- Solo hashes sembrados y PRNGs; la misma semilla para imagen y sonido cuando deben coincidir.
- Las búsquedas hacia atrás reproducen píxeles idénticos; prueba t = 0 después de un fotograma tardío.
preserveDrawingBuffer: true,antialias: false; llama agl.finish()al final derenderFrame.- El modo de vista previa se repite con
requestAnimationFrame;?render=1no dibuja nada por sí mismo. renderAudiodevuelve el mismo búfer cada vez que se llama, comparado muestra a muestra en dos renderizados; el volumen y el pico verdadero se miden, no se adivinan.- Inspecciona fotogramas fijos en el evento de luz, un fotograma antes y el último fotograma; verifica la temporización por fotograma.
Evitar
- Contornos de dibujos animados, trazos brillantes alrededor de planetas, nebulosas púrpuras saturadas, preajustes de destello de lente con anillos de hexágonos.
- Globos giratorios, movimientos rápidos de cámara, sacudidas o líneas de velocidad sin una causa física.
- Recortar destellos a blanco plano, negros elevados, bandeado (añade dither sub-LSB antes de la salida).
- Granulado en pantalla completa por fotograma o destellos de 1 píxel; estroboscopían y engordan H.264.
- Efectos de sonido en cada movimiento, whooshes cursis, subidas que no llevan a ninguna parte, clics en los bordes del búfer, colas de reverberación cortadas por el final de la película.
- Texto, logotipos o interfaz de usuario a menos que el resumen los solicite.