phase + opti #190

Merged
Nora merged 5 commits from feature/motion-oil-sheen into develop 2026-09-13 09:53:49 +00:00
Owner
No description provided.
phase + opti
All checks were successful
CI / Renderer - couverture JS (pull_request) Has been skipped
CI / PHP - tests + static + lint (pull_request) Successful in 8m28s
CI / Renderer - audit des dépendances JS (pull_request) Successful in 42s
CI / Renderer - tests + lint JS (pull_request) Successful in 6m41s
e3ac1c3b31
perf(low-mist): la frame arrête de refaire ce qui n'a pas bougé
All checks were successful
CI / Renderer - couverture JS (pull_request) Has been skipped
CI / Renderer - audit des dépendances JS (pull_request) Successful in 1m54s
CI / PHP - tests + static + lint (pull_request) Successful in 7m2s
CI / Renderer - tests + lint JS (pull_request) Successful in 7m57s
4c703a598e
Le banc T44 gardait `phase` « de justesse » à 288,7 ms contre 315 de budget,
mais mesurait à 1493 x 1920 — la taille de tournage d'avant le fond perdu. Au
cadre réel (1557 x 1920) le même code sortait à 328,6 ms, et sur quatorze
tirages uniformes du paramSpec dix dépassaient (médiane 353, pire 525).

Aucune des trois issues de la fiche n'est jouée : on pose la question
d'oil-sheen à la place. Trois réponses, aucune ne déplace un octet.

- L'IMMOBILE du clip (`stillOf`) : les deux bruits échantillonnés sur la grille
  et la densité de départ ne dépendent pas de la rotation du champ. Posés sur
  l'ardoise de clip quand la vidéo en fournit une (`config.videoCache`).
- La trame (`raster`) : 2,9 M de pixels qui allouaient deux objets chacun
  (`normalized`, `sampleGradient`) et rechargeaient quatre coins de grille que
  cinq pixels voisins se partagent. 190 -> 82 ms.
- La diffusion (`blur`) : neuf rabattements de bord par cellule et par pas,
  31 M de clamps par frame, désormais tabulés. 119 -> 78 ms.

Protocole T44, 1557 x 1920, machine de dev 12 coeurs : 328,6 -> 161,4 ms/frame
aux défauts ; médiane 202 sur les quatorze tirages, pire 305, zéro au-dessus du
budget. Le coin du paramSpec reste hors budget (448 ms, 142 %), réserve écrite
dans le module avec l'ordre des leviers : `meta.videoParams` avant de toucher
au défaut de `grid`.

Contrairement à oil-sheen, le raccourci ne coûte aucune approximation : les
boucles chaudes sont réécrites à arithmétique identique et l'ardoise n'est
qu'un calcul qu'on ne refait pas. Parité d'octets vérifiée sur les trois
colorMode, les deux bouts du paramSpec et son coin, ardoise froide comme
chaude — ni golden, ni ENGINE_VERSION, ni VIDEO_ENGINE_VERSION, et l'estampe
accélère autant que le film.

`loopedWeights` sort de lib/loop-field.js pour les appelants qui balaient des
milliers de cellules au même tour ; `loopedValue` passe par lui, donc le repli
de `t` vient toujours en premier et les deux chemins ne peuvent pas diverger.

Reste hors code : le rebuild de l'image renderer.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QgrLtPxVFc81NTodU8NLHx
Chaque op réaffectait globalAlpha, globalCompositeOperation et sa couleur,
même quand la précédente portait déjà les mêmes. Sur un flux fait de longues
séries homogènes — les 27 740 marques de traînée de rain-glass sont toutes le
même destination-out dans la même couleur — ces écritures traversent le pont
napi et jettent la peinture que skia tenait en cache : un cinquième du coût de
la frame, pour un résultat qui ne change pas d'un pixel.

Le suivi d'état vaut pour un appel : alpha et composite partent des valeurs
neutres, où le reset final laisse toujours le ctx, mais aucune couleur n'est
supposée survivre d'un paint à l'autre (la toile persistante d'un draw-on en
reçoit un par frame).

assertFiniteOp parcourt les clés en for-in : mêmes clés sur un littéral, sans
allouer un tableau de paires par op (17 → 2 ms sur 35 000 ops).

Byte-identique : les 70 goldens passent. rain-glass, la frame la plus lourde
du catalogue : 371 → 293 ms.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QgrLtPxVFc81NTodU8NLHx
absorb balayait tout le tableau pour chaque goutte qui dévale, à chaque pas, et
posait à chaque couple deux racines (les rayons, recalculés depuis les masses)
puis une hypoténuse. Sur les défauts, 21 millions de couples : 238 ms, la
moitié du coût d'une frame.

Deux calculs qu'on ne refait plus, aucun qu'on change :

- le rayon suit la masse au lieu d'être redérivé — même appel, même valeur, mis
  à jour aux deux seuls endroits où une masse bouge (la condensation, l'avalage) ;
- |dx| puis |dy| avant la racine : ils minorent la distance, donc une goutte
  écartée par la boîte l'aurait été par le disque. Mêmes absorptions, dans le
  même ordre.

Byte-identique : le golden ne bouge pas. Simulation 238 → 79 ms ; la frame la
plus lourde 616 → 388 ms.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QgrLtPxVFc81NTodU8NLHx
done
All checks were successful
CI / Renderer - couverture JS (pull_request) Has been skipped
CI / Renderer - audit des dépendances JS (pull_request) Successful in 1m14s
CI / PHP - tests + static + lint (pull_request) Successful in 5m43s
CI / Renderer - tests + lint JS (pull_request) Successful in 6m22s
b699980d58
Nora merged commit 2a3abf5492 into develop 2026-09-13 09:53:49 +00:00
Nora deleted branch feature/motion-oil-sheen 2026-09-13 09:53:49 +00:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Nora/ArtAutomatic!190
No description provided.