[{"data":1,"prerenderedAt":165},["ShallowReactive",2],{"case-\u002Fcases\u002Fhero-shader-reveal":3},{"id":4,"title":5,"body":6,"description":151,"extension":152,"meta":153,"navigation":160,"path":161,"seo":162,"stem":163,"__hash__":164},"content\u002Fcases\u002Fhero-shader-reveal.md","Hero shader — reveal par traînée",{"type":7,"value":8,"toc":144},"minimark",[9,13,17,24,27,32,40,65,68,72,113,117],[10,11,5],"h1",{"id":12},"hero-shader-reveal-par-traînée",[14,15,16],"p",{},"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.",[18,19,21],"shader-frame",{"bg":20},"#f5f4ef",[22,23],"hero-reveal",{},[14,25,26],{},"Bouge la souris sur le cadre.",[28,29,31],"h2",{"id":30},"démarche","Démarche",[14,33,34,35,39],{},"Deux passes de rendu par frame, orchestrées par un ",[36,37,38],"strong",{},"ping-pong de render targets"," :",[41,42,43,55],"ol",{},[44,45,46,49,50,54],"li",{},[36,47,48],{},"Trail pass"," — lit l'ancienne traînée (texture 1024×1024, canal R), la multiplie par ",[51,52,53],"code",{},"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.",[44,56,57,60,61,64],{},[36,58,59],{},"Display pass"," — lit la traînée fraîche, calcule la nébuleuse cachée (même shader que le hero bleu\u002Fviolet), et ",[51,62,63],{},"mix(base, hidden, reveal)"," pour composer l'image finale.",[14,66,67],{},"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.",[28,69,71],{"id":70},"détails-techniques","Détails techniques",[73,74,75,85,95,101,107],"ul",{},[44,76,77,80,81,84],{},[36,78,79],{},"Segment, pas point"," — la traînée peint un segment ",[51,82,83],{},"mousePrev → mouse",", pas juste un disque à la position actuelle. Quand la souris bouge vite, pas de trous dans le trait.",[44,86,87,90,91,94],{},[36,88,89],{},"Décollage propre"," — flag ",[51,92,93],{},"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.",[44,96,97,100],{},[36,98,99],{},"Edge halo"," dans le display — léger assombrissement au bord du reveal pour un effet « épaisseur » \u002F 3D plutôt que mask net.",[44,102,103,106],{},[36,104,105],{},"Grain conditionnel"," — le grain de film ne s'applique qu'aux zones révélées. La base blanche reste pristine.",[44,108,109,112],{},[36,110,111],{},"Correction d'aspect"," dans la trail pass — sinon le pinceau devient une ellipse horizontale sur les écrans larges.",[28,114,116],{"id":115},"pile","Pile",[14,118,119,126,127,130,131,130,134,130,137,130,140,143],{},[120,121,125],"a",{"href":122,"rel":123},"https:\u002F\u002Fgithub.com\u002Foframe\u002Fogl",[124],"nofollow","OGL"," — ",[51,128,129],{},"Renderer",", ",[51,132,133],{},"Program",[51,135,136],{},"Mesh",[51,138,139],{},"Triangle",[51,141,142],{},"RenderTarget",". Deux programmes shaders, un seul triangle plein écran, deux RenderTargets ping-pong. Pas de dépendance 3D ni de framework de postprocessing.",{"title":145,"searchDepth":146,"depth":146,"links":147},"",2,[148,149,150],{"id":30,"depth":146,"text":31},{"id":70,"depth":146,"text":71},{"id":115,"depth":146,"text":116},"Base blanche homogène, la souris révèle progressivement une nébuleuse cachée dessous via une traînée qui s'estompe.","md",{"tags":154},[155,156,157,158,159],"webgl","glsl","ogl","feedback-texture","shader",true,"\u002Fcases\u002Fhero-shader-reveal",{"title":5,"description":151},"cases\u002Fhero-shader-reveal","6v46yuqYz4BhYiY6DhDo3QrO2OTvwwuZv9BTSNswYIw",1794436389541]