X Motion · Orbit
Orbit estende x-motion; não o substitui. Execute o método principal (brief, tese, storyboard, crítica) e use este arquivo para a direção de arte e as receitas. Foi escrito para filmes de 8 a 12 segundos, 1920×1080, 30 qps, renderizados deterministicamente a partir de renderFrame(t) em Chromium headless com WebGL de software.
Tese visual
O espaço é preto, e a luz é o evento. Uma fonte (o sol) e os materiais que ela toca: atmosfera, oceano, nuvem, metal. Cada filme é construído em torno do único momento em que a luz chega, cruza uma borda ou se liberta.
Confiança silenciosa sobre espetáculo. O quadro é majoritariamente preto verdadeiro; o assunto é uma massa grande e lenta (um planeta, uma lua, uma porta de abóbada) e uma borda fina e brilhante. Se um quadro parece um papel de parede ou um menu de jogo, remova coisas até que pareça uma fotografia tirada por uma câmera paciente.
Paleta
Trabalhe em HDR linear e faça o mapeamento tonal (tonemap) no final; estes são alvos referenciados à tela para onde o olho deve pousar.
| Função | Hex | Uso |
|---|---|---|
| Preto verdadeiro | #000000 | 60–80% da maioria dos quadros. Nunca eleve com névoa. |
| Azul-marinho do vazio | #050b18 | Gradiente de espaço profundo, longe de qualquer luz. |
| Azul-marinho profundo | #0b1a33 | Oceano noturno, metal sombreado, céu escuro após um "levantamento". |
| Azul Rayleigh | #2f6fd8 | Corpo da atmosfera no lado diurno. |
| Ciano atmosférico | #8fd3ff | Borda Fresnel, linha fina do limbo. |
| Dourado do amanhecer | #ffc46b | Queda do núcleo solar, terminador, primeira luz nos topos das nuvens. |
| Âmbar de brasa | #ffa448 | Luzes da cidade (sódio) no lado noturno. |
| Pérola da coroa | #ece8de | Coroa, estrelas, realces semelhantes a sinos. |
| Titânio | #8a8f96 | Corpo de metal escovado. |
| Níquel | #c3c6c8 | Realces de metal, faces planas de chanfro. |
| Champanhe | #e9d4a6 | Borda especular quente no metal; no máximo uma linha de 2 px. |
| Verde aurora | #4ff0a0 | Aurora de oxigênio; mantenha abaixo de 20% de seu valor total. |
| Rosa H-alfa | #ff4a6e | Apenas para proeminências solares e cromosfera. |
Luz e material
- Uma luz. O sol é a única fonte. Brilhos, bordas e cintilações devem ser explicados por sua posição. Cidades e auroras são as únicas emissoras, e elas vivem no lado noturno.
- Escurecimento do limbo para qualquer disco estelar:
I(mu) = 1 - 0,6*(1 - mu)commu = sqrt(1 - r*r); um núcleo dourado-para-branco parece quente, um disco plano parece um adesivo. - Atmosfera é espalhamento, não um traço. Azul (Rayleigh) no limbo iluminado, dourado onde a luz roça o terminador, brilho espalhado para frente quando o sol está atrás do planeta. A borda é fina: cerca de 1,5% do raio do planeta.
- Lado noturno não é preto: um preenchimento frio de luar mantém o oceano azul profundo (nunca verde-oliva), a terra um tom neutro mais escuro, nuvens prateadas-brancas, uma borda Fresnel ciana na borda do disco, aglomerados de âmbar de cidade seguindo litorais, e uma linha tênue de ar-verde (airglow) no limbo. O dourado quente aparece apenas onde o sol realmente alcança.
- Brilho do oceano: um lóbulo especular suave onde o sol reflete, alongado em direção ao limbo; apenas oceano.
- Metal: titânio escovado é anisotrópico. Os realces se estendem através da direção da escovação, chanfros pegam uma borda fina de champanhe, costuras recebem oclusão. Sem espelho cromado, sem ruído de bump map.
- Lente: um traço anamórfico (horizontal, fino, com tom ciano), dois a quatro fantasmas fracos ao longo da linha através do centro do quadro. Opacidade do fantasma abaixo de 4%. Mapeamento tonal com uma curva estilo ACES; nunca recorte um realce para branco liso por mais de alguns pixels.
Composição
- Horizontes ficam em um terço, nunca no centro. Limbos de planetas são arcos grandes (raio 1,5–4 alturas de quadro); um globo pequeno inteiro parece um brinquedo.
- O evento de luz (crista do sol, anel de diamante, primeira luz) cai em um terço, não no centro exato, a menos que o plano seja sobre simetria (uma porta de abóbada, um eclipse).
- Mantenha as estrelas esparsas (algumas centenas visíveis), tamanho 1–2 px com queda suave, ligeiramente quentes ou frias por temperatura. Elas aparecem quando o quadro escurece e desaparecem quando clareia, como faria a exposição.
- Sem texto, logotipos, HUDs, papel de parede de nebulosa ou sujeira de lente. Um assunto de cada vez.
Vocabulário de movimento e tempo
Verbos: selar, destravar, separar, cair, subir, surgir, planar, engolir, desdobrar, libertar, levantar. A câmera nunca treme e raramente corta; a massa se move devagar, a luz se move rápido.
| Batida | Duração típica | Curva |
|---|---|---|
| Segurar em um quadro selado ou escuro | 1,0–1,5 s | estático, apenas varredura de luz |
| Destravamento mecânico | 0,10–0,20 s | saída rápida suave, pequeno assentamento |
| Portas se abrindo / queda | 0,8–1,4 s | início lento, aceleração exponencial |
| Distorção (traços) | 1,2–2,0 s | pico inicial, decaimento suave até a imobilidade; esparso, quadro permanece majoritariamente preto |
| Subida de planeta / deslize orbital | 3–6 s | longo ease-in-out, nunca linear |
| Crista do sol ou anel de diamante | 0,3–0,6 s até o clarão total | início abrupto, desabrochar lento |
| Resolução e espera | ≥ 1,5 s | quase parado; deixe o acorde soar |
O movimento é calculado em forma fechada a partir de t: posições são integrais de curvas de velocidade autorais, nunca acumuladas por quadro. A viagem de distorção é s(t) = integral de v, então o comprimento do traço é s(t) - s(t - shutter). Mantenha os traços poucos (dezenas por camada, não centenas), longos e suaves, com camadas distantes mais escuras e finas que as próximas; uma explosão densa e uniforme parece hiperespaço genérico.
Paleta sonora e mixagem
- Sub (senoides de 30–60 Hz com ondas lentas) carrega a massa. Aplique um filtro passa-alta no mestre a cerca de 25 Hz (em JS após a renderização; veja a receita de áudio mestre).
- Metal: síntese modal. Um clique de ruído passa-banda de 5–10 ms mais 4–6 parciais senoidais inarmônicos (por exemplo 1,00, 2,32, 3,86, 5,40 vezes f0) com decaimentos de 0,1–0,8 s.
- Ar e viagem: ruído semeado através de um passa-banda móvel, panorâmico com a imagem. Sem whooshes prontos.
- Harmonia: pads suspensos (sus2, sus4) sob tensão; resolva para um add9 maior no evento de luz. Pads são 3 serras desafinadas por nota através de um passa-baixa de 600–1800 Hz.
- Sinos: parciais inarmônicos aditivos (1, 2,0, 2,76, 4,07, 5,4) com ataque de 3–8 ms e decaimentos que encurtam com o índice da parcial.
- Reverberação: um
ConvolverNodecom um impulso estéreo semeado (decaimento exponencial de 2,5–4,5 s, pré-atraso de 20 ms, cauda mais escura). - Silêncio é uma deixa. Afine o som quando a imagem escurecer; deixe o evento de luz possuir o primeiro momento alto.
- Alvos: integrado −18 LUFS, pico verdadeiro ≤ −1,5 dBFS, cauda totalmente decaída 0,3 s antes do final. Meça em código, normalize e depois limite.
Receitas técnicas
Pipeline. WebGL de software é lento, então divida o trabalho: uma passagem de meia resolução renderiza a cena HDR suave (planeta, atmosfera, coroa) em uma textura RGBA16F; uma passagem de resolução total faz o upsampling e adiciona detalhes nítidos (estrelas, luzes da cidade, clarão, bordas de metal), depois mapeia tons e aplica dither. Meça segundos por quadro; fique abaixo de 1,5 s em 1080p.
Raio–esfera. Analítico, sem marching para a superfície:
vec2 sphere(vec3 ro, vec3 rd, float R) { // t próximo, t distante; t < 0 significa erro
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);
}
Atmosfera. Espalhamento único ao longo do raio de visão dentro da concha (8–12 passos), com a profundidade óptica do caminho da luz aproximada em 3–4 passos. Coeficientes de Rayleigh vec3(5.8, 13.5, 33.1) (escalados para o raio do seu planeta), Mie com uma fase de Henyey–Greenstein g = 0.76. Pule pixels cujo raio nunca entra na concha.
Luzes da cidade. Ruído hash de cluster, mascarado por terra e por noite:
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
Estrelas, com limite de banda. Uma estrela por célula da grade, perturbada; desenhe com uma Gaussiana de pelo menos 0,8 px sigma, para que o movimento nunca cause cintilação:
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;
Clarão da crista do sol. Tudo é analítico em torno da posição de tela do sol s e sua fração visível v (calculada em 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 em g, 2–4 % */ }
Titânio escovado. Realce anisotrópico com a tangente ao longo da direção da escovação, mais traços fracos com limite de banda (comprimento de onda ≥ 3 px):
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. Lua ligeiramente maior que o sol (1,04–1,08). Dê ao limbo lunar um pouco de ruído para que as contas de Baily e um anel de diamante apareçam naturalmente perto do contato. Coroa: brilho pow(r, -3) vezes streamers de ruído em (ângulo, log r), mais filamentos finos de ruído de alta frequência angular e baixa frequência radial.
Escreva o perfil do limbo uma vez como uma soma de senoides de frequência inteira e entalhes Gaussianos envoltos, depois emita-o tanto como JS quanto como uma string GLSL. O JS pode então integrar a fotosfera visível por quadro (uma bisseção por raio centrado no sol, cerca de 700 raios), o que dá a fração visível, o centróide da conta para o brilho intenso e os tempos de contato exatos para a trilha. O brilho da conta precisa de um mapeamento logarítmico da fração, como log(1 + f*1e6) / log(1 + 1e6). O brilho amplo desenhado a partir de mipmaps grossos mostra uma escada em fontes HDR, então desfoque cada nível com quatro taps bilineares em deslocamentos de meio texel.
Áudio mestre (determinístico). Após startRendering(), meça o LUFS integrado (ponderação K e gating BS.1770) em JS, escale para −18, depois execute um limitador de pico lookahead em picos superamostrados 4× a −1,5 dBFS. Semeie cada buffer de ruído e impulso com mulberry32.
No Chromium headless, estes falham em um teste de repetição bit-exato: um sinal estéreo através de um BiquadFilterNode ou DynamicsCompressorNode mestre, e qualquer nó com três ou mais entradas, porque a ordem da soma varia em um ULP. Mantenha o barramento mestre livre de nós (ganho para o destino). Execute o passa-alta e a compressão do barramento em JS após a renderização. Incorpore o passa-alta de uma reverberação em seu impulso. Encadeie cada fan-in através de ganhos de 2 entradas, já que a + b é exata e comutativa.
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 verificação determinística
renderFrame(t)define cada uniforme apenas a partir det; nenhumDate,performance.now,Math.randomou acumulação por quadro no modo de renderização.- Apenas hashes e PRNGs semeados; a mesma semente para imagem e som quando devem concordar.
- Retrocessos reproduzem pixels idênticos; teste t = 0 após um quadro tardio.
preserveDrawingBuffer: true,antialias: false; chamegl.finish()no final derenderFrame.- O modo de visualização loopa com
requestAnimationFrame;?render=1não desenha nada por conta própria. renderAudioretorna o mesmo buffer a cada chamada, comparado amostra por amostra em duas renderizações; loudness e pico verdadeiro são medidos, não adivinhados.- Inspecione quadros estáticos no evento de luz, um quadro antes dele e o último quadro; verifique o tempo por quadro.
Evite
- Contornos de desenho animado, traços brilhantes ao redor de planetas, nebulosas roxas saturadas, predefinições de clarão de lente com anéis de hexágonos.
- Globos girando, movimentos rápidos de câmera, tremedeira ou linhas de velocidade sem causa física.
- Recortar realces para branco liso, pretos levantados, bandeamento (adicione dither sub-LSB antes da saída).
- Grão de tela cheia por quadro ou faíscas de 1 px; eles cintilam e incham o H.264.
- Efeitos sonoros em cada movimento, whooshes bregas, rises que não vão a lugar nenhum, cliques nas bordas do buffer, caudas de reverberação cortadas pelo final do filme.
- Texto, logotipos ou cromo de interface a menos que o brief os solicite.