Peindre le verre et le tube
AquaTube n'affiche pas un skin dessiné dans Photoshop. Le verre et l'écran cathodique sont calculés à chaque image. Pourquoi ré-embrasser le Frutiger Aero et la télé cathodique en 2026, et ce que ça change.
Un objet, pas une image
Les vieux skins de lecteurs multimédia étaient des images. Un artiste dessinait une coque brillante dans un éditeur, découpait les boutons, et le programme collait cette image à l'écran. AquaTube ne fonctionne pas comme ça. Le pod n'est pas une image : c'est une fonction, recalculée à chaque frame par un shader.
Ce choix n'est pas gratuit. Un objet réagit : la lumière glisse dessus quand on le bouge, il change de teinte selon le thème, il respire au rythme du son. Une image ne fait rien de tout ça. Pour que le pod se comporte comme un objet de verre et pas comme un autocollant, il fallait le décrire comme un objet : des formes, des matériaux, une réaction à la lumière. Le skeuomorphisme, ici, n'est pas une décoration ajoutée après coup. C'est le modèle de rendu lui-même.
Conséquence concrète : les six thèmes de coque ne sont pas six images, mais six jeux de cinq couleurs passés au même shader. Ajouter un thème coûte cinq couleurs, pas une planche de dessin.
Le verre
La silhouette du pod vient d'une fonction de distance signée (SDF) : pour chaque pixel, elle dit à quelle distance on est du bord de la forme. Positif dehors, négatif dedans, zéro sur le contour. C'est ce qui donne un bord net à n'importe quelle taille, sans crénelage, et une silhouette qu'on peut arrondir, biseauter, ombrer à volonté.
À partir de cette distance, le reste est de la simulation de lumière sur du verre mouillé : un reflet en dôme sur le haut, une lumière de bord (rim light) qui détache la forme du fond, un voile de brillance (sheen), des bulles aqua qui montent en fondu additif, et des boutons en "gel" avec reflet spéculaire, relief et ombre portée. Chaque effet répond à la même question : comment la lumière se comporterait sur cet objet, à cet endroit. C'est ça qui fait qu'on lit du verre et pas un aplat coloré.
fn sd_round_box(p: vec2<f32>, b: vec2<f32>, r: f32) -> f32 {
let q = abs(p) - b + r;
return min(max(q.x, q.y), 0.0) + length(max(q, vec2<f32>(0.0))) - r;
}Le tube
L'écran, au centre du pod, n'est pas une simple zone vidéo. Il passe par un traitement cathodique. Et le piège, c'est de croire que c'est de la nostalgie décorative. Ce n'est pas ça. Le rendu CRT recrée les défauts physiques d'un vieux tube : la courbure du verre, la persistance du phosphore, la légère aberration chromatique, les scanlines, le vignettage, le grain. Des défauts, précisément, que ton œil pardonnait à l'époque sans même les voir.
La persistance du phosphore, par exemple, garde une trace de l'image précédente qui s'éteint doucement. Une seule texture d'historique suffit, mélangée à l'image courante par un maximum atténué :
La courbure pose un problème que les vraies télés avaient aussi : en bombant l'image, les bords sortent du cadre (l'overscan). Plutôt que de laisser des bandes noires ou une image étirée aux coins, je courbe puis je compense, pour que l'image courbée rentre pile dans l'écran quelle que soit l'intensité de courbure :
Tous ces effets sont réglables (courbure, scanline, aberration, vignette, grain), parce qu'un défaut trop appuyé cesse d'être crédible et devient un filtre Instagram. L'aberration par défaut a d'ailleurs fini adoucie : trop forte, elle trahissait l'effet au lieu de le vendre.
// persistance phosphore : trainee attenuee de la frame precedente
let out_rgb = mix(cur.rgb, max(cur.rgb, h.rgb * 0.88), scr_mask);
// simplifie pour l'illustration
fn curve(uv: vec2<f32>, amt: f32) -> vec2<f32> {
let c = uv * 2.0 - 1.0;
let off = c * dot(c, c) * amt;
return (c + c * off) / (1.0 + amt) * 0.5 + 0.5; // courbe + compense l'overscan
}La passe volume
Un objet skeuomorphique ne tient que s'il a du relief. Plat, le pod redevient une image. À un moment, il manquait de volume : la coque paraissait trop lisse, les contrôles trop timides. J'ai fait une passe dédiée pour donner du corps : coque bombée (reflet en dôme plus ombre de forme), contrôles massifs (galets de gel plus gros, mieux espacés, avec ombre portée), verre plus épais (biseau sur le pourtour, écran enfoncé dans la coque).
Rien de tout ça ne se décide dans le code. Ça se juge à l'image, un composant à la fois : on pousse un paramètre, on capture, on regarde si l'objet gagne en présence ou s'il devient lourd. Le relief est une affaire de perception, pas de valeurs. Le code ne fait que proposer ; c'est la capture qui tranche.
Ce que je retiens
Le procédural coûte cher à l'écriture. Décrire du verre comme une réaction à la lumière est beaucoup plus long que de peindre une jolie coque une bonne fois. Mais ce coût est un investissement : une fois l'objet décrit comme objet, il se décline presque gratuitement (six thèmes en cinq couleurs), il réagit tout seul (thème, son, lumière), et il reste net à toutes les tailles.
Et le skeuomorphisme, quand on le prend au sérieux, n'est pas une nostalgie. C'est un pari sur la mémoire du corps : on sait comment se comporte du verre, on sait ce que fait une vieille télé. Recréer ces comportements, défauts compris, c'est parler à cette mémoire. Une interface plate demande qu'on l'apprenne ; un objet, on le reconnaît.