X Motion · Orbit
Orbit étend x-motion ; il ne le remplace pas. Lancez la méthode de base (brief, thèse, storyboard, critique) et utilisez ce fichier pour la direction artistique et les recettes. Il a été écrit pour des films de 8 à 12 secondes, en 1920×1080, 30 ips, rendus de manière déterministe à partir de renderFrame(t) dans Chromium headless avec WebGL logiciel.
Thèse visuelle
L'espace est noir, et la lumière est l'événement. Une seule source (le soleil) et les matériaux qu'elle touche : atmosphère, océan, nuage, métal. Chaque film est construit autour de l'instant unique où la lumière arrive, franchit un limbe, ou se libère.
Confiance calme plutôt que spectacle. Le cadre est surtout d'un noir véritable ; le sujet est une grande masse lente (une planète, une lune, une porte de voûte) et un mince bord lumineux. Si une image ressemble à un fond d'écran ou à un menu de jeu, retirez des éléments jusqu'à ce qu'elle ressemble à une photographie prise par un appareil patient.
Palette
Travaillez en HDR linéaire et appliquez le mappage de tons à la fin ; ce sont des cibles de référence d'affichage pour ce que l'œil doit voir.
| Rôle | Hex | Utilisation |
|---|---|---|
| Noir véritable | #000000 | 60–80 % de la plupart des images. Ne l'élevez jamais avec de la brume. |
| Marine du vide | #050b18 | Dégradé d'espace profond, loin de toute lumière. |
| Marine profond | #0b1a33 | Océan nocturne, métal ombragé, ciel sombre après un « soulèvement ». |
| Bleu Rayleigh | #2f6fd8 | Corps de l'atmosphère du côté jour. |
| Cyan atmosphérique | #8fd3ff | Bordure de Fresnel, fine ligne de limbe. |
| Or du lever du soleil | #ffc46b | Dégradation du noyau solaire, terminateur, première lumière sur les nuages. |
| Ambre braise | #ffa448 | Lumières de la ville (sodium) du côté nuit. |
| Perle de la couronne | #ece8de | Couronne solaire, étoiles, reflets de cloche. |
| Titane | #8a8f96 | Corps métallique brossé. |
| Nickel | #c3c6c8 | Reflets métalliques, plats de biseau. |
| Champagne | #e9d4a6 | Bordure spéculaire chaude sur le métal ; au maximum une ligne de 2 px. |
| Vert aurore | #4ff0a0 | Aurore d'oxygène ; maintenez-la en dessous de 20 % de sa valeur maximale. |
| Rose H-alpha | #ff4a6e | Protubérances solaires et chromosphère uniquement. |
Lumière et matériau
- Une lumière. Le soleil est la seule source. Les lueurs, les bordures et les reflets doivent être expliqués par sa position. Les villes et les aurores sont les seules émetteurs, et elles vivent du côté nuit.
- Assombrissement du limbe pour tout disque stellaire :
I(mu) = 1 - 0.6*(1 - mu)avecmu = sqrt(1 - r*r); un noyau or-à-blanc semble chaud, un disque plat semble collé. - L'atmosphère est une diffusion, pas un trait. Bleu (Rayleigh) sur le limbe éclairé, or là où la lumière effleure le terminateur, luminosité diffusée vers l'avant lorsque le soleil est derrière la planète. La bordure est fine : environ 1,5 % du rayon planétaire.
- Le côté nuit n'est pas noir : un remplissage clair de lune garde l'océan bleu profond (jamais olive), la terre une nuance neutre plus foncée, les nuages blanc argenté, une bordure de Fresnel cyan sur le bord du disque, des grappes de villes ambre suivant les côtes, et une faible ligne d'airglow verte au limbe. L'or chaud n'apparaît que là où le soleil atteint réellement.
- Reflet océanique : un lobe spéculaire doux là où le soleil se reflète, allongé vers le limbe ; océan uniquement.
- Métal : le titane brossé est anisotrope. Les reflets s'étirent dans la direction du brossage, les biseaux attrapent une fine bordure champagne, les jointures reçoivent de l'occlusion. Pas de miroir chromé, pas de bruit de relief.
- Objectif : une traînée anamorphique (horizontale, fine, teintée de cyan), deux à quatre fantômes faibles le long de la ligne passant par le centre du cadre. Opacité des fantômes inférieure à 4 %. Mappage de tons avec une courbe de style ACES ; n'écrêtez jamais un reflet en blanc plat sur plus de quelques pixels.
Composition
- Les horizons reposent sur un tiers, jamais par le centre. Les limbes planétaires sont de grands arcs (rayon de 1,5 à 4 fois la hauteur du cadre) ; un petit globe entier ressemble à un jouet.
- L'événement lumineux (crête solaire, anneau de diamant, première lumière) se pose sur un tiers, pas au centre, sauf si le plan est symétrique (une porte de voûte, une éclipse).
- Gardez les étoiles clairsemées (quelques centaines visibles), de taille 1–2 px avec un dégradé doux, légèrement chaudes ou froides selon la température. Elles apparaissent lorsque le cadre s'assombrit et disparaissent lorsqu'il devient lumineux, comme le ferait une exposition.
- Pas de texte, logos, HUD, fond d'écran de nébuleuse ou saleté d'objectif. Un seul sujet à la fois.
Vocabulaire du mouvement et timing
Verbes : sceller, déverrouiller, séparer, tomber, s'élever, crêter, glisser, avaler, se déplier, se libérer, soulever. La caméra ne tremble jamais et coupe rarement ; la masse se déplace lentement, la lumière se déplace vite.
| Temps | Durée typique | Courbe |
|---|---|---|
| Maintien sur un cadre scellé ou sombre | 1,0–1,5 s | statique, balayage lumineux uniquement |
| Déverrouillage mécanique | 0,10–0,20 s | sortie rapide avec atténuation, petit ajustement |
| Portes qui se séparent / traversée | 0,8–1,4 s | début lent, accélération exponentielle |
| Distorsion (traînées) | 1,2–2,0 s | pic précoce, décroissance douce vers l'immobilité ; sparse, le cadre reste principalement noir |
| Lever de planète / glissement orbital | 3–6 s | longue entrée-sortie douce, jamais linéaire |
| Crête solaire ou anneau de diamant | 0,3–0,6 s jusqu'à l'éclat complet | début net, bloom lent |
| Résolution et maintien | ≥ 1,5 s | presque immobile ; laissez sonner l'accord |
Le mouvement est calculé sous forme fermée à partir de t : les positions sont des intégrales de courbes de vélocité définies, jamais accumulées par image. Le voyage de distorsion est s(t) = integral of v, donc la longueur de traînée est s(t) - s(t - shutter). Gardez les traînées rares (dizaines par couche, pas des centaines), longues et douces, avec des couches lointaines plus sombres et plus fines que les proches ; une rafale uniforme dense ressemble à de l'hyperspace de stock.
Palette sonore et mixage
- Sub (sinusoïdes 30–60 Hz avec des gonflements lents) porte la masse. Passe-haut le master à environ 25 Hz (en JS après le rendu ; voir la recette du master audio).
- Métal : synthèse modale. Un clic de bruit passé-bande de 5–10 ms plus 4–6 partiels sinusoïdaux inharmoniques (par exemple 1,00, 2,32, 3,86, 5,40 fois f0) avec des décroissances de 0,1–0,8 s.
- Air et voyage : bruit ensemencé à travers un passe-bande mobile, panoramique avec l'image. Pas de whooshes de stock.
- Harmonie : pads suspendus (sus2, sus4) sous tension ; résoudre à un add9 majeur lors de l'événement lumineux. Les pads sont 3 scies désaccordées par note à travers un passe-bas de 600–1800 Hz.
- Cloches : partiels inharmoniques additifs (1, 2,0, 2,76, 4,07, 5,4) avec une attaque de 3–8 ms et des décroissances qui raccourcissent avec l'indice du partiel.
- Réverbération : un
ConvolverNodeavec une impulsion stéréo ensemencée (décroissance exponentielle de 2,5 à 4,5 s, pré-délai de 20 ms, queue plus sombre). - Le silence est un signal. Épaississez le son lorsque l'image s'assombrit ; laissez l'événement lumineux posséder le premier moment fort.
- Objectifs : intégré −18 LUFS, crête réelle ≤ −1,5 dBFS, queue complètement atténuée 0,3 s avant la fin. Mesurez dans le code, normalisez, puis limitez.
Recettes techniques
Pipeline. WebGL logiciel est lent, donc divisez le travail : un passage en demi-résolution rend la scène HDR lisse (planète, atmosphère, couronne) dans une texture RGBA16F ; un passage en pleine résolution la sur-échantillonne et ajoute des détails nets (étoiles, lumières de la ville, éclat, bords métalliques), puis applique le mappage de tons et le tramage. Mesurez les secondes par image ; restez en dessous de 1,5 s à 1080p.
Rayon–sphère. Analytique, pas de marching pour la surface :
vec2 sphere(vec3 ro, vec3 rd, float R) { // t près, t loin ; t < 0 signifie manqué
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);
}
Atmosphère. Diffusion unique le long du rayon de vue à l'intérieur de la coque (8–12 pas), avec la profondeur optique du trajet lumineux approximée en 3–4 pas. Coefficients de Rayleigh vec3(5.8, 13.5, 33.1) (mis à l'échelle de votre rayon planétaire), Mie avec une phase Henyey–Greenstein g = 0.76. Sautez les pixels dont le rayon n'entre jamais dans la coque.
Lumières de la ville. Bruit de hachage cluster, masqué par la terre et par la nuit :
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; // ambre, HDR
Étoiles, limitées en bande. Une étoile par cellule de grille, hachées ; dessinez avec une Gaussienne d'au moins 0,8 px sigma, donc le mouvement ne stroboscope jamais :
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;
Éclat de crête solaire. Tout est analytique autour de la position à l'écran du soleil s et de sa fraction visible v (calculée 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]; /* disque doux à g, 2–4 % */ }
Titane brossé. Reflet anisotrope avec la tangente le long de la direction du brossage, plus des traînées faibles limitées en bande (longueur d'onde ≥ 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;
Éclipse. Lune légèrement plus grande que le soleil (1,04–1,08). Donnez un peu de bruit au limbe lunaire pour que les perles de Baily et un anneau de diamant apparaissent naturellement près du contact. Couronne : luminosité pow(r, -3) fois des stries à partir du bruit dans (angle, log r), plus des filaments fins provenant d'un bruit à haute fréquence angulaire et à basse fréquence radiale.
Écrivez le profil du limbe une fois comme une somme de sinus de fréquence entière et d'encoches gaussiennes enveloppées, puis émettez-le à la fois comme JS et comme chaîne GLSL. JS peut alors intégrer la photosphère visible par image (une bisection par rayon centré sur le soleil, environ 700 rayons), ce qui donne la fraction visible, le centroïde des perles pour l'éblouissement et les temps de contact exacts pour la partition. L'éblouissement des perles a besoin d'un mappage logarithmique de la fraction, comme log(1 + f*1e6) / log(1 + 1e6). L'éblouissement large dessiné à partir de mipmaps grossières montre une marche d'escalier sur les sources HDR, donc floutez chaque niveau avec quatre taps bilinéaires à des décalages de demi-texel.
Master audio (déterministe). Après startRendering(), mesurez le LUFS intégré (pondération K BS.1770 et portillon) en JS, mettez à l'échelle à −18, puis exécutez un limiteur de crête avec anticipation sur les pics sur-échantillonnés 4× à −1,5 dBFS. Semez chaque tampon de bruit et d'impulsion avec mulberry32.
Dans Chromium headless, ceux-ci échouent à un test de répétition bit-exact : un signal stéréo traversant un BiquadFilterNode ou DynamicsCompressorNode master, et tout nœud avec trois entrées ou plus, car l'ordre de sommation varie d'une ULP. Gardez le bus master sans nœud (gain vers destination). Exécutez le passe-haut et la compression de bus en JS après le rendu. Incorporez le passe-haut d'une réverbération dans son impulsion. Enchaînez chaque fan-in à travers des gains à 2 entrées, car a + b est exact et commutatif.
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;};}
Liste de contrôle déterministe
renderFrame(t)définit chaque uniforme à partir detuniquement ; pas deDate,performance.now,Math.randomou accumulation par image en mode rendu.- Uniquement des hachages et PRNG ensemencés ; la même graine pour l'image et le son lorsqu'ils doivent correspondre.
- Les retours en arrière reproduisent des pixels identiques ; testez t = 0 après une image tardive.
preserveDrawingBuffer: true,antialias: false; appelezgl.finish()à la fin derenderFrame.- Le mode aperçu boucle avec
requestAnimationFrame;?render=1ne dessine rien par lui-même. renderAudiorenvoie le même tampon à chaque appel, comparé échantillon par échantillon sur deux rendus ; la sonie et la crête réelle sont mesurées, pas devinées.- Inspectez les images fixes à l'événement lumineux, une image avant et la dernière image ; vérifiez le timing par image.
Évitez
- Contours de dessin animé, traits lumineux autour des planètes, nébuleuses violettes saturées, préréglages de flare d'objectif avec des anneaux d'hexagones.
- Globes tournants, mouvements rapides de caméra, secousses ou lignes de vitesse sans cause physique.
- Écrêtage des reflets en blanc plat, noirs relevés, bandes (ajoutez un tramage sous-LSB avant la sortie).
- Grain plein écran par image ou paillettes 1 px ; ils stroboscopent et gonflent H.264.
- Effets sonores sur chaque mouvement, whooshes ringards, montées qui ne mènent nulle part, clics aux bords des tampons, queues de réverbération coupées par la fin du film.
- Texte, logos ou chrome d'interface sauf si le brief les demande.