Hero shader — reveal par traînée

Au repos, un fond blanc homogène. Dès que la souris bouge, elle « gratte » le blanc pour révéler un paysage coloré caché dessous. La trace s'efface lentement quand on arrête.

Bouge la souris sur le cadre.

Démarche

Deux passes de rendu par frame, orchestrées par un ping-pong de render targets :

  1. Trail pass — lit l'ancienne traînée (texture 1024×1024, canal R), la multiplie par uDecay = 0.98 (lingering ~1 s), et peint un segment doux de la position précédente de la souris à la position actuelle. Le résultat devient la nouvelle texture de traînée.
  2. Display pass — lit la traînée fraîche, calcule la nébuleuse cachée (même shader que le hero bleu/violet), et mix(base, hidden, reveal) pour composer l'image finale.

Le ping-pong (deux RenderTargets alternés) est nécessaire parce qu'on ne peut pas lire et écrire la même texture dans la même passe.

Détails techniques

  • Segment, pas point — la traînée peint un segment mousePrev → mouse, pas juste un disque à la position actuelle. Quand la souris bouge vite, pas de trous dans le trait.
  • Décollage propre — flag interacted : tant que la souris n'a pas bougé, aucun paint. Le premier mouvement snap les positions pour qu'aucune ligne ne soit tirée du centre.
  • Edge halo dans le display — léger assombrissement au bord du reveal pour un effet « épaisseur » / 3D plutôt que mask net.
  • Grain conditionnel — le grain de film ne s'applique qu'aux zones révélées. La base blanche reste pristine.
  • Correction d'aspect dans la trail pass — sinon le pinceau devient une ellipse horizontale sur les écrans larges.

Pile

OGL — Renderer, Program, Mesh, Triangle, RenderTarget. Deux programmes shaders, un seul triangle plein écran, deux RenderTargets ping-pong. Pas de dépendance 3D ni de framework de postprocessing.

© 2026 Alla Lozinskaya