{"componentChunkName":"component---src-templates-blog-post-js","path":"/fr/blog/hacking-through-shaders/","result":{"data":{"site":{"siteMetadata":{"title":"A Game Studio","author":"Lythom"}},"markdownRemark":{"id":"c5a862c5-f752-5eca-95db-91acae69c013","html":"<p>N’importe quel programmeur sain d’esprit enseignerait “Lisez la documentation, comprenez ce que vous faites, et vous serez capable de résoudre vos problèmes”. Tout à fait vrai ! Mais il y a un défaut : plus le sujet est vaste ou profond, plus le temps nécessaire à son apprentissage est grand. Parfois, “hacker” son chemin pourrait suffire. Et puis la vie est plus amusante avec un brin de folie non ? Trafiquons les shaders !</p>\n<div style=\"text-align:center\">\n<video autoplay=\"autoplay\" loop=\"loop\" width=\"320\" height=\"320\">\n    <source src=\"/1e21a8b71d904eb4d8c1316559f078e5/test6.mp4\" type=\"video/mp4\" />\n</video>\n</div>\n<h2 id=\"un-pas-en-arrière\" style=\"position:relative;\"><a href=\"#un-pas-en-arri%C3%A8re\" aria-label=\"un pas en arrière permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Un pas en arrière</h2>\n<p>Ok oui il y a des choses que vous devez savoir avant de plonger dans les shaders, les voici :</p>\n<ol>\n<li>\n<p>Un shader contient 3 parties importantes : les déclarations, la fonction <code class=\"language-text\">vertex</code> et la fonction <code class=\"language-text\">fragment</code>.</p>\n<ul>\n<li>Les déclarations vous permettent de piloter ou de configurer le shader à partir d’un script.</li>\n<li>La fonction <code class=\"language-text\">vertex</code> vous permet de manipuler le monde 3D (déplacement de vectrices).</li>\n<li>La fonction <code class=\"language-text\">fragment</code> vous permet de manipuler les pixels rendus à l’écran.</li>\n</ul>\n</li>\n<li>Une couleur est représentée par un vecteur à 4 dimensions <code class=\"language-text\">fixed4</code>.</li>\n<li>Dans la fonction <code class=\"language-text\">fragment</code>, vous ne manipulez qu’un seul pixel à la fois.</li>\n<li>La fonction <code class=\"language-text\">frac(float)</code> renvoie la partie décimale d’un nombre à virgule flottante.</li>\n<li><code class=\"language-text\">text2D(sampler2D,float2)</code> donne la couleur des pixels de la texture <code class=\"language-text\">sample2D</code> à la coordonnée <code class=\"language-text\">float2</code>. Vous obtenez cette coordonnée en paramètre d’entrée dans la fonction <code class=\"language-text\">fragment</code>.</li>\n<li>Les coordonnées sont comprises entre (0,0) et (1,1).</li>\n</ol>\n<p>Ça peut sembler très spécifique si les shaders sont nouveaux pour vous, mais ce sont en fait des choses que vous trouveriez tôt dans votre apprentissage des shaders.</p>\n<h2 id=\"plusieurs-couches-de-rendu\" style=\"position:relative;\"><a href=\"#plusieurs-couches-de-rendu\" aria-label=\"plusieurs couches de rendu permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Plusieurs couches de rendu</h2>\n<p>Je travaille sur un jeu appelé <a href=\"https://a-time-paradox.com/\">A Time Paradox</a> qui se déroule dans un univers futuriste (dans un vaisseau spatial chevauchant un horizon de trou noir). Une façon d’évoquer un monde futuriste est d’utiliser quelque chose de typique, attrayant et rapide à créer : des hologrammes.</p>\n<p>Voici l’idée : nous allons afficher une texture de projecteur (spotlight) en arrière-plan, puis animer une texture de bruit (glitch) sur le dessus pour simuler des lignes de balayage. Le plan ? Trouver un shader 2D assez simple comme point de départ, puis ajouter une texture de glitch par dessus la texture principale. Enfin, s’amuser avec des maths pour animer la texture de glitch.</p>\n<p>En avant !</p>\n<h3 id=\"shader-de-départ\" style=\"position:relative;\"><a href=\"#shader-de-d%C3%A9part\" aria-label=\"shader de départ permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Shader de départ</h3>\n<blockquote>\n<p>Note : J’utilise Unity et paint.NET comme outils mais la façon de faire fonctionnerait pour n’importe quel moteur ou technologie supportant les shaders et n’importe quel éditeur d’images.</p>\n</blockquote>\n<p>Sur <a href=\"https://unity3d.com/fr/get-unity/download/archive\">https://unity3d.com/fr/get-unity/download/archive</a> vous trouverez sous “téléchargements (votre plate-forme)” une entrée nommée “shaders intégrés”. Il contient tous les shaders de Unity et ils peuvent être copié/collé/modifié dans votre projet. J’ai choisi de commencer avec le shader <code class=\"language-text\">DefaultResourcesExtra\\Unlit\\Unlit-Alpha.shader</code> puisque je travaille en 2D sans éclairage et avec transparence. Il ressemble à ça :</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"glsl\"><pre class=\"language-glsl\"><code class=\"language-glsl\"><span class=\"token comment\">// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)</span>\n\n<span class=\"token comment\">// Unlit alpha-blended shader.</span>\n<span class=\"token comment\">// - no lighting</span>\n<span class=\"token comment\">// - no lightmap support</span>\n<span class=\"token comment\">// - no per-material color</span>\n\nShader <span class=\"token string\">\"Unlit/Transparent\"</span> <span class=\"token punctuation\">{</span>\n<span class=\"gatsby-highlight-code-line\">Properties <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">    _MainTex <span class=\"token punctuation\">(</span><span class=\"token string\">\"Base (RGB) Trans (A)\"</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span>D<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token string\">\"white\"</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span></span><span class=\"gatsby-highlight-code-line\"><span class=\"token punctuation\">}</span></span>\nSubShader <span class=\"token punctuation\">{</span>\n    Tags <span class=\"token punctuation\">{</span><span class=\"token string\">\"Queue\"</span><span class=\"token operator\">=</span><span class=\"token string\">\"Transparent\"</span> <span class=\"token string\">\"IgnoreProjector\"</span><span class=\"token operator\">=</span><span class=\"token string\">\"True\"</span> <span class=\"token string\">\"RenderType\"</span><span class=\"token operator\">=</span><span class=\"token string\">\"Transparent\"</span><span class=\"token punctuation\">}</span>\n    LOD <span class=\"token number\">100</span>\n\n    ZWrite Off\n    Blend SrcAlpha OneMinusSrcAlpha\n\n    Pass <span class=\"token punctuation\">{</span>\n        CGPROGRAM\n            <span class=\"token preprocessor builtin\">#pragma</span> vertex vert\n            <span class=\"token preprocessor builtin\">#pragma</span> fragment frag\n            <span class=\"token preprocessor builtin\">#pragma</span> target <span class=\"token number\">2.0</span>\n            <span class=\"token preprocessor builtin\">#pragma</span> multi_compile_fog\n\n            <span class=\"token preprocessor builtin\">#</span>include <span class=\"token string\">\"UnityCG.cginc\"</span>\n\n            <span class=\"token keyword\">struct</span> appdata_t <span class=\"token punctuation\">{</span>\n                float4 vertex <span class=\"token punctuation\">:</span> POSITION<span class=\"token punctuation\">;</span>\n                float2 texcoord <span class=\"token punctuation\">:</span> TEXCOORD0<span class=\"token punctuation\">;</span>\n                UNITY_VERTEX_INPUT_INSTANCE_ID\n            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n            <span class=\"token keyword\">struct</span> v2f <span class=\"token punctuation\">{</span>\n                float4 vertex <span class=\"token punctuation\">:</span> SV_POSITION<span class=\"token punctuation\">;</span>\n                float2 texcoord <span class=\"token punctuation\">:</span> TEXCOORD0<span class=\"token punctuation\">;</span>\n                <span class=\"token function\">UNITY_FOG_COORDS</span><span class=\"token punctuation\">(</span><span class=\"token number\">1</span><span class=\"token punctuation\">)</span>\n                UNITY_VERTEX_OUTPUT_STEREO\n            <span class=\"token punctuation\">}</span><span class=\"token punctuation\">;</span>\n\n            <span class=\"token keyword\">sampler2D</span> _MainTex<span class=\"token punctuation\">;</span>\n            float4 _MainTex_ST<span class=\"token punctuation\">;</span>\n\n            v2f vert <span class=\"token punctuation\">(</span>appdata_t v<span class=\"token punctuation\">)</span>\n            <span class=\"token punctuation\">{</span>\n                v2f o<span class=\"token punctuation\">;</span>\n                <span class=\"token function\">UNITY_SETUP_INSTANCE_ID</span><span class=\"token punctuation\">(</span>v<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                <span class=\"token function\">UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO</span><span class=\"token punctuation\">(</span>o<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                o<span class=\"token punctuation\">.</span>vertex <span class=\"token operator\">=</span> <span class=\"token function\">UnityObjectToClipPos</span><span class=\"token punctuation\">(</span>v<span class=\"token punctuation\">.</span>vertex<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                o<span class=\"token punctuation\">.</span>texcoord <span class=\"token operator\">=</span> <span class=\"token function\">TRANSFORM_TEX</span><span class=\"token punctuation\">(</span>v<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">,</span> _MainTex<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                <span class=\"token function\">UNITY_TRANSFER_FOG</span><span class=\"token punctuation\">(</span>o<span class=\"token punctuation\">,</span>o<span class=\"token punctuation\">.</span>vertex<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n                <span class=\"token keyword\">return</span> o<span class=\"token punctuation\">;</span>\n            <span class=\"token punctuation\">}</span>\n\n<span class=\"gatsby-highlight-code-line\">            fixed4 frag <span class=\"token punctuation\">(</span>v2f i<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">:</span> SV_Target</span><span class=\"gatsby-highlight-code-line\">            <span class=\"token punctuation\">{</span></span><span class=\"gatsby-highlight-code-line\">                fixed4 col <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_MainTex<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">                <span class=\"token function\">UNITY_APPLY_FOG</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">.</span>fogCoord<span class=\"token punctuation\">,</span> col<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">                <span class=\"token keyword\">return</span> col<span class=\"token punctuation\">;</span></span><span class=\"gatsby-highlight-code-line\">            <span class=\"token punctuation\">}</span></span>        ENDCG\n    <span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span><span class=\"token punctuation\">}</span></code></pre></div>\n<p>On trouve ici les “Properties”, ainsi que les fonctions “vert” et “frag”. La fonction frag fait globalement la chose suivante : rechercher la couleur du pixel dans <code class=\"language-text\">_MainTex</code> qui est situé à la position <code class=\"language-text\">i.texcoord</code>, exécuter un processus <code class=\"language-text\">UNITY_APPLY_FOG_FOG</code> que nous ne connaissons pas, retourner la couleur.</p>\n<p>Avant tout, faisons fonctionner ce shader :</p>\n<ol>\n<li>copier/coller le fichier shader dans le dossier assets du projet;</li>\n<li>dans le fichier shader ligne 8, renommer le shader de <code class=\"language-text\">Shader Unlit/Transparent</code> en <code class=\"language-text\">Shader Custom/MyHologram</code> ;</li>\n<li>dans l’éditeur de Unity, cliquez avec le bouton droit de la souris sur le fichier shader -> create -> material pour créer un nouveau material associé au shader ;</li>\n<li>créer (voir ci-dessous), puis glisser-déposer le sprite “spotlight” depuis les assets vers la scène ;</li>\n<li>glisser-déposer le material du dossier asset vers le sprite dans la hiérarchie de la scène pour que le sprite utilise le material configuré avec notre shader.</li>\n</ol>\n<p>Le sprite “spotlight” ? Utilisons celui là :</p>\n<div style=\"width:250px;margin:auto;\">\n    <span class=\"gatsby-resp-image-wrapper\" style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 512px; \">\n      <a class=\"gatsby-resp-image-link\" href=\"/static/86cfd55c0239b23f0bf31a5c1be79530/01e7c/spot.png\" style=\"display: block\" target=\"_blank\" rel=\"noopener\">\n    <span class=\"gatsby-resp-image-background-image\" style=\"padding-bottom: 100%; position: relative; bottom: 0; left: 0; background-image: url(&apos;data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAC4jAAAuIwF4pT92AAAB7ElEQVQ4y+2Ty27UMBSGj6dIrJAoA6pQ1UpVKULTMpfOJGn3gNruALHiUpUtay4SAp6AXh6BKuPkOJNYArZVF1VfomwRz8Fvx8lkphex6BJL3/z2sX38H8dD7URSZxBb2gOmdsK0jL6XMnUxbpnYII91rLLVNsYtrG2WYKxiuvzWgcO70T5Nhd9oNpQ0sx9SIwppNYUjZpqXEc3HETVY0qJi0eK+WGYpGnEoFjkW95jFHSnFguyLJkcE2zF1U54E9W6q6j1oz/ZLbhb0UuVgRz7G3C2zFlchrEs/UzdAy8vUEvS+watQjUGbBm+IiXWCTNXLsudQGiYCsAYegId+ziODdwb+kHWMV2ejPhXurE2cMI3+FngJXo2gy/7mGCb2OtBqusyFH5OsSP4EfAJvwfsL+ADegS9mjzWkE1Nl7hInCKe3wVcs2gU7jt1z2APbYKpaqXVoVauaG5tSfoA+iEfQiqEGCX6CF25PrZpr3OV18B0cIcEBOLRkuSJ+AI6BXtHJtereMmHF5YTT54j9ASdj/LJo9Rv61CWbOMudpQjigq+i/xG8AY/N0/B1sgF95j7GZy9LrhSJVtz+kebr4ksn//y39UoD6vQk7mNYembd1i7Cq6w9txUnBZUSgjHn9t3icEPx/v63y21/AXwWn2JP+WOxAAAAAElFTkSuQmCC&apos;); background-size: cover; display: block;\"></span>\n  <img class=\"gatsby-resp-image-image\" alt=\"spot\" title=\"spot\" src=\"/static/86cfd55c0239b23f0bf31a5c1be79530/01e7c/spot.png\" srcset=\"/static/86cfd55c0239b23f0bf31a5c1be79530/12f09/spot.png 148w,\n/static/86cfd55c0239b23f0bf31a5c1be79530/e4a3f/spot.png 295w,\n/static/86cfd55c0239b23f0bf31a5c1be79530/01e7c/spot.png 512w\" sizes=\"(max-width: 512px) 100vw, 512px\" style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\" loading=\"lazy\">\n  </a>\n    </span>\n</div>\n<p>Cela devrait donner le résultat suivant :\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 590px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/ee36889d92e1a39aa6d0b8b9b3c03b1e/f6f7a/step1.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 89.86486486486487%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAASCAYAAABb0P4QAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAClUlEQVQ4y5VUW2sTYRDdXNoku0kobbGJFtRcNslms5vrbmJjaIoWtT5Y8iL4YGmhBRUV/AdCwRdB8Qcf50wuJg2ofTh8s5PvO3M7E6PRaKBaraJYLKJQKCxQLJXRCg7g+N3Fb+Wy+Jo+6vW6+uYoFIpwXVdhOI6jhJVKBaVSSR/R5lkuFWHb02/CcWoYPX4kGCEIA/R6PUUYBOgPBgiCEIZt2yApo67DXdi8w7vtdhvdTge+74PVzeE3m+iI32DkXC6HnZ0d7O7uLs5l0JfP5zXLMAynpN0ujo6OMB6PMT48xJOnx+j3+1PCzc1NGIbxV6RSKW0NiTzP01IvL69wcXGB8/NzvD07w3A4nBLyMh9FIpE1orkvnU4rYavVQlvAMoNZtvS1WLIEU8JkMvnPDC3LUkJmEcgQSMLy/wwm1EC3JpxMJko6kKkSzKrdbqF/MBS7NyNMJP6LkHfZP5bZlBJ1ujJtVxQwOH6KDntIKZhbW4iaKcTk0RrSFiKWicz2thKyPMqDMqrVagvwW4Vti4AtkUW67iDr1pFZwNUz6zVgVSvISNCKBA9FGqPRSEmZ3TKYtZac2NhAxveQP32FvZPn2Ht5gpxg7+QF7k5OkXxwH6a0pSqZ6JSl5JtkFDZPoyKNTsQ3EMtk8PDdFYqfPqDwkXiP0pfP2H/zemUo89KWt4RY7LLq0DT10Z1nx/B+/UDt+iucb9do/PyOjOyv6lACkrA5y4S2/gdIG8hBuy7BVmQTkzNdsZHcvwdTyqR9UzZBr60lM9OG5yPoD/TbE5sKuJUOefdApEEd6nYIUW8mcpKx9HXC5fVbsklo65QHuiF8TJJ5T1d6yMvRaBTxeByxWGwF9PG3bDarhNxfSoeP51kt4zfXkfbqwU/yKAAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"Unity screenshot\"\n        title=\"Unity screenshot\"\n        src=\"/static/ee36889d92e1a39aa6d0b8b9b3c03b1e/fcda8/step1.png\"\n        srcset=\"/static/ee36889d92e1a39aa6d0b8b9b3c03b1e/12f09/step1.png 148w,\n/static/ee36889d92e1a39aa6d0b8b9b3c03b1e/e4a3f/step1.png 295w,\n/static/ee36889d92e1a39aa6d0b8b9b3c03b1e/fcda8/step1.png 590w,\n/static/ee36889d92e1a39aa6d0b8b9b3c03b1e/efc66/step1.png 885w,\n/static/ee36889d92e1a39aa6d0b8b9b3c03b1e/f6f7a/step1.png 1009w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<h3 id=\"ajouter-une-texture-de-glitch\" style=\"position:relative;\"><a href=\"#ajouter-une-texture-de-glitch\" aria-label=\"ajouter une texture de glitch permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Ajouter une texture de glitch</h3>\n<p>Ajoutons une nouvelle texture de glitch. Nous pourrions soit en trouver une en ligne, soit la créer nous-même. Voici comment j’ai créé la mienne :</p>\n<ol>\n<li>Créez un fichier png 1024x1024 entièrement noir.</li>\n<li>Sur un nouveau calque, tracez au hasard des lignes blanches horizontales de 3 pixels de hauteur.</li>\n<li>Dupliquer le dernier calque créé, appliquer un “effet de flou de mouvement” vers le haut de 10px</li>\n<li>Répétez l’étape 3. quelques fois jusqu’à avoir un dégradé lisse.</li>\n<li>Enlever la couche de ligne d’origine (le blanc pur est trop dur et tranchant).</li>\n<li>Fusionner toutes les couches restantes.</li>\n</ol>\n<p>Vous devriez obtenir quelque chose comme ça (j’ai aussi un peu modifié la courbe de luminosité) :\n<span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 590px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/e4a0fde4181690628adfe4ea5f61f528/2bef9/scanlines.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 100%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAC4gAAAuIAHVHB4bAAAAZElEQVQ4y63TsQkAIRQE0c1/biKYWoOpIIiBfdiBbVjx3hUxC6+ACVZrLZOUczZJe2+T9N4zSXNOk/TPqN67STrnmMQnR4RJwp+CJ5dSTNK91yQ+OaVkksYYJvHJtVaT1Foz6QMZGXZb5VNICwAAAABJRU5ErkJggg=='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"scanlines\"\n        title=\"scanlines\"\n        src=\"/static/e4a0fde4181690628adfe4ea5f61f528/fcda8/scanlines.png\"\n        srcset=\"/static/e4a0fde4181690628adfe4ea5f61f528/12f09/scanlines.png 148w,\n/static/e4a0fde4181690628adfe4ea5f61f528/e4a3f/scanlines.png 295w,\n/static/e4a0fde4181690628adfe4ea5f61f528/fcda8/scanlines.png 590w,\n/static/e4a0fde4181690628adfe4ea5f61f528/efc66/scanlines.png 885w,\n/static/e4a0fde4181690628adfe4ea5f61f528/2bef9/scanlines.png 1024w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<p>Pour l’utiliser dans notre shader, recopions ce qui est fait pour le <code class=\"language-text\">_MainText</code>.</p>\n<p>Ligne 11, ajoutons la propriété <code class=\"language-text\">_GlitchTex</code> :</p>\n<div class=\"gatsby-highlight\" data-language=\"glsl\"><pre class=\"language-glsl\"><code class=\"language-glsl\">Properties <span class=\"token punctuation\">{</span>\n    _MainTex <span class=\"token punctuation\">(</span><span class=\"token string\">\"Base (RGB) Trans (A)\"</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span>D<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token string\">\"white\"</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n    _GlitchTex <span class=\"token punctuation\">(</span><span class=\"token string\">\"Glitch Texture\"</span><span class=\"token punctuation\">,</span> <span class=\"token number\">2</span>D<span class=\"token punctuation\">)</span> <span class=\"token operator\">=</span> <span class=\"token string\">\"white\"</span> <span class=\"token punctuation\">{</span><span class=\"token punctuation\">}</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>Puis ligne 44, ajouter la déclaration <code class=\"language-text\">_GlitchTex</code> :</p>\n<div class=\"gatsby-highlight\" data-language=\"glsl\"><pre class=\"language-glsl\"><code class=\"language-glsl\"><span class=\"token keyword\">sampler2D</span> _MainTex<span class=\"token punctuation\">;</span>\n<span class=\"token keyword\">sampler2D</span> _GlitchTex<span class=\"token punctuation\">;</span>\nfloat4 _MainTex_ST<span class=\"token punctuation\">;</span></code></pre></div>\n<p>A partir de ce point, la propriété “Glitch texture” devrait apparaître dans l’inspecteur du sprite “spotlight” dans Unity. Sélectionnez la texture que vous venez de créer (ou utilisez la mienne) comme valeur.</p>\n<p>Et… il ne se passe rien. En effet, nous devons maintenant utiliser au niveau du rendu la texture que nous avons déclarée dans le code du shader. Que les maths commencent !</p>\n<h3 id=\"maths-et-fun\" style=\"position:relative;\"><a href=\"#maths-et-fun\" aria-label=\"maths et fun permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Maths et fun</h3>\n<p>Pour changer le rendu des pixels, la fonction <code class=\"language-text\">fragment</code> est celle que nous devons modifier :</p>\n<div class=\"gatsby-highlight\" data-language=\"glsl\"><pre class=\"language-glsl\"><code class=\"language-glsl\">fixed4 frag <span class=\"token punctuation\">(</span>v2f i<span class=\"token punctuation\">)</span> <span class=\"token punctuation\">:</span> SV_Target\n<span class=\"token punctuation\">{</span>\n    fixed4 col <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_MainTex<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token function\">UNITY_APPLY_FOG</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">.</span>fogCoord<span class=\"token punctuation\">,</span> col<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    <span class=\"token keyword\">return</span> col<span class=\"token punctuation\">;</span>\n<span class=\"token punctuation\">}</span></code></pre></div>\n<p>L’objectif est d’afficher la couleur de notre texture “glitch”, essayons de copier le code utilisé pour <code class=\"language-text\">_MainTex</code> et de mélanger les 2 couleurs.</p>\n<div class=\"gatsby-highlight\" data-language=\"glsl\"><pre class=\"language-glsl\"><code class=\"language-glsl\">    fixed4 mainCol <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_MainTex<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    fixed4 glitchCol <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_GlitchTex<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    fixed4 col <span class=\"token operator\">=</span> mainCol <span class=\"token operator\">+</span> glitchCol<span class=\"token punctuation\">;</span></code></pre></div>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 460px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/caabad309bea257b2486557113f3030d/08a84/test1.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.83783783783784%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAA7DAAAOwwHHb6hkAAACJ0lEQVQ4y62TXUhTYRjH3x1H4kXCqCw2CEqCrdaHJoSGS4m67yI1yYjE0iQqgsiMBanFjFVYmJ4p4T460+Zc2/QYOoONCqLRpxfVRd1kLvoQZ2RX/95zznt0qwZddPHj/zz/c/jzvM95DyGE4H/BabUgB252Ys9lGyrtdlTf6EAF34UaysEeByq7u7C3h0ed4EF9vxdHvALq3S40+n2o9Q3geDCAk6KIw8NhHJ2IYG1xMcgkgFeMScZLyosUffZb/5zVkh+nvKb0xePQaDQgpeetqHn6BFXR+9j3IMqIyVrF+mqZGIN6D2MM5Z39jx9BX1CgHJ3Ly4PZ44TJ64bxthNGwQWTQHuhj+FkuFJqBaP7FjaF/DA0NshhGo6TlKC8uRlXfv5A69QHXPyU+CfaEtOwffmMprdvsNRgUKaTjiwVy1auwrV379E7Pw9+dhaOZBKOuSR4laSCg6nkdc98g4vursJqVabLymKhyphYvnsXto0EUdjvwdY7wgKFjDRvwIOigA8bOztA1KBFFpvN9nZYxkSU3B3E9tDQAiVqHQ4oGvTDMi5ihaWUfQguPVCdMn+HBZdmvqIl8REt01MyrUxlqH+B7rn9+xwODQ1muuAkdaEwnz2DndEIykbDKI+MKkzcU3RsRPbLxBB0G9b/bbo/A7P1emzp5WG+fhXrzjUh//QprDlxTFaTrQ1F9HqtrqvNFJa+Q5UlubkZ/9dsnQ7anJyMz38BgRA5HpXDvFAAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"test1\"\n        title=\"test1\"\n        src=\"/static/caabad309bea257b2486557113f3030d/08a84/test1.png\"\n        srcset=\"/static/caabad309bea257b2486557113f3030d/12f09/test1.png 148w,\n/static/caabad309bea257b2486557113f3030d/e4a3f/test1.png 295w,\n/static/caabad309bea257b2486557113f3030d/08a84/test1.png 460w\"\n        sizes=\"(max-width: 460px) 100vw, 460px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<p>Super, nous avons mélangé les 2 textures en 1 rendu ! Mais ça a l’air bizarre, n’est-ce pas ? L’alpha de la première image semble ne plus fonctionner : le dégradé lisse que nous avions est perdu et les bords ont l’air faux. Essayons de multiplier au lieu d’additionner pour mélanger les couleurs.</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"glsl\"><pre class=\"language-glsl\"><code class=\"language-glsl\">    fixed4 mainCol <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_MainTex<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    fixed4 glitchCol <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_GlitchTex<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">    fixed4 col <span class=\"token operator\">=</span> mainCol <span class=\"token operator\">*</span> glitchCol<span class=\"token punctuation\">;</span></span></code></pre></div>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 460px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/d4b52bc17f91c31135d469f5293eca65/08a84/test2.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.83783783783784%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAq0lEQVQ4y63TXQuDIBQGYDVLU6qboGLtg7n9/5/4zmPFRri1yIuHAyqv5xQyxhiS4kWBfwmiYhR4nk+BQmtkxhxjLbiUS5eJR57aFKFlumW3ZdTPQNowtyusczDu7muMW/FrzweKto106ImyhKxrr5rrhqoKZ3mWxQPTfsMZja66DqrvvaWuddDDANk024H0c+iwHkfv9FV5OYextwNTj/x+Pr+eFp/sCjzgBa1TEYEP1DfWAAAAAElFTkSuQmCC'); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"test2\"\n        title=\"test2\"\n        src=\"/static/d4b52bc17f91c31135d469f5293eca65/08a84/test2.png\"\n        srcset=\"/static/d4b52bc17f91c31135d469f5293eca65/12f09/test2.png 148w,\n/static/d4b52bc17f91c31135d469f5293eca65/e4a3f/test2.png 295w,\n/static/d4b52bc17f91c31135d469f5293eca65/08a84/test2.png 460w\"\n        sizes=\"(max-width: 460px) 100vw, 460px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<p>Pas mal, mais on ne reconnait pas le sprite d’origine. Cela dit, on pourrait utiliser ce résultat comme “couche supplémentaire” non ? Additionnons ce rendu (<code class=\"language-text\">mainCol * glitchCol</code>) avec la couleur d’origine (<code class=\"language-text\">mainCol</code>).</p>\n<div class=\"gatsby-highlight has-highlighted-lines\" data-language=\"glsl\"><pre class=\"language-glsl\"><code class=\"language-glsl\">    fixed4 mainCol <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_MainTex<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    fixed4 glitchCol <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_GlitchTex<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"gatsby-highlight-code-line\">    fixed4 col <span class=\"token operator\">=</span> mainCol <span class=\"token operator\">*</span> glitchCol <span class=\"token operator\">+</span> mainCol<span class=\"token punctuation\">;</span></span></code></pre></div>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 460px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/1c86cf46ce6ee67f7b2beddb69753b25/08a84/test3.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 62.83783783783784%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAANCAYAAACpUE5eAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAB5UlEQVQ4y63Ty0sbURQH4MnEJEYjJu1CA6P4lhJEqfMwRnHjs74iXfmKLqSltFURuit0q5QKLkRw4UKSGE184YNWRFp049qFrbSK1rYLpS78A36dO3cmGWvUjYuPczgXztxz71yGYRjcK4PFDIPJBIPZHMWqlDWLJYrVJCZeZ7WCYVkwqcXFcPD8VYIQI4qKBxqJkKIcsoceD2wFBXSHJHG2eZHW1Ij0liZVM9Wq1wKniuTp3qtMdrs6trxN59M2ZPT6wHV1gOvuVGQQPorzdclRp4fiujuQ9bwPjjJJPT8DiYxSkObDKPVPgw/6Y2b8EGa0GIAQCoAPkRiUawGIkTmUTIwjwWbTXwxNpIUIGv+eoe74EA2nx4r6X3onaJAp8bccfx6h+fICWc/6aCMjGxuZJCmuRyhbWYS0OCcLU0thiCpJEaG1hVm415dRNDYa79eJzo7cwX6Uf1yFEA5CnJ+9WSQE99oS7HwpbcKy8RtaMzNR/XUPtSc/UHP4DbX/OzpAzfd9PDn/g5LJCf1FXD9D7SvkTKp2d+DZ2kDl9paiQvNlE57PG3B/WkVyft4dDVXGpCS43g/D9WEEeW+GkPP6JbJfvUDu0AAK373F4+kpcJ3t8UaN35AgT/Gmt2qUn9ht6/8ADMyz7IELYsIAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"test3\"\n        title=\"test3\"\n        src=\"/static/1c86cf46ce6ee67f7b2beddb69753b25/08a84/test3.png\"\n        srcset=\"/static/1c86cf46ce6ee67f7b2beddb69753b25/12f09/test3.png 148w,\n/static/1c86cf46ce6ee67f7b2beddb69753b25/e4a3f/test3.png 295w,\n/static/1c86cf46ce6ee67f7b2beddb69753b25/08a84/test3.png 460w\"\n        sizes=\"(max-width: 460px) 100vw, 460px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<p>Hé ! On s’approche !</p>\n<p>Maintenant, il est temps d’animer le glitch. Pour cela, nous aurons besoin d’une sorte de variable basée sur le temps. Chaque moteur fournit un moyen d’accéder à une horloge, Unity fournit <code class=\"language-text\">_Time.y</code>. L’idée est de modifier le <code class=\"language-text\">texcoord</code> (rappel : c’est un <code class=\"language-text\">vector2</code> entre 0,0 et 1,1 pour les coordonnées x,y), pour que la valeur y soit modifiée dans le temps et bouclée entre 0 et 1 pour faire un défilement infini.</p>\n<p>Pour boucler une variable qui dépend du temps entre 0 et 1, nous pouvons faire comme suit :</p>\n<div class=\"gatsby-highlight\" data-language=\"glsl\"><pre class=\"language-glsl\"><code class=\"language-glsl\">    <span class=\"token keyword\">fixed</span> scrollValue <span class=\"token operator\">=</span> <span class=\"token function\">frac</span><span class=\"token punctuation\">(</span><span class=\"token number\">0.04</span> <span class=\"token operator\">*</span> _Time<span class=\"token punctuation\">.</span>y<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p><code class=\"language-text\">_Time.y</code> est une valeur qui augmente indéfiniement (temps écoulé en secondes depuis de début du jeu), <code class=\"language-text\">frac()</code> ne conserve que la partie décimale d’un nombre à virgule flottante (faisant boucler la valeur entre 0 et 1), 0.04 est une constante arbitraire utilisée comme ratio pour ralentir l’effet de défilement. Cette constante pourrait être extraite comme propriété du shader pour configurer la vitesse, mais gardons-la inline pour le moment.</p>\n<p>Afin de remapper la position statique de <code class=\"language-text\">texcoord</code> dans sa version “scrollée”, nous devons créer un nouveau texcoord <code class=\"language-text\">float2</code>, et changer sa valeur y pour appliquer le défilement.</p>\n<div class=\"gatsby-highlight\" data-language=\"glsl\"><pre class=\"language-glsl\"><code class=\"language-glsl\">    float2 offsetTexCoord <span class=\"token operator\">=</span> <span class=\"token function\">float2</span><span class=\"token punctuation\">(</span>\n        i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">.</span>x<span class=\"token punctuation\">,</span>\n        <span class=\"token function\">frac</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">.</span>y <span class=\"token operator\">+</span> <span class=\"token number\">0.04</span> <span class=\"token operator\">*</span> _Time<span class=\"token punctuation\">.</span>y<span class=\"token punctuation\">)</span>\n    <span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n    fixed4 glitchCol <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_GlitchTex<span class=\"token punctuation\">,</span> offsetTexCoord<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Ici, on conserve la valeur x tel quel, et on ajoute notre valeur de scroll qui varie en fonction du temps. Ça indique au shader, pour un pixel donné, de regarder une position verticale différente à l’intérieur de la texture au fil du temps. Parce que cette position verticale se déplace lentement, elle rend la texture “décalée”. Et c’est parti !</p>\n<div style=\"text-align:center\">\n    <video autoplay=\"autoplay\" loop=\"loop\" width=\"320\" height=\"320\">\n        <source src=\"/885403ce0018471ca9d2721563772c9a/test4.mp4\" type=\"video/mp4\" />\n    </video>\n</div>\n<p>Remarque: j’ai triché un peu pour obtenir une boucle d’animation parfaite, votre hologramme devrait se déplacer un peu moins vite.</p>\n<h3 id=\"we-need-to-go-deeper-nous-devons-aller-plus-loin\" style=\"position:relative;\"><a href=\"#we-need-to-go-deeper-nous-devons-aller-plus-loin\" aria-label=\"we need to go deeper nous devons aller plus loin permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>We need to go deeper (Nous devons aller plus loin)</h3>\n<p>Le rendu est déjà bien, mais notre machine à reconnaissance de motifs (notre cerveau) trouvera rapidement la répétition et perdra rapidement son intérêt pour le visuel. Peu importe, nous avons plus d’un tour dans notre sac ! On pourra par exemple utiliser plusieurs couches de glitch qui défilent à des vitesses différentes. Dans l’idée, on copie/colle le même code que précédemment mais avec des décalages différents pour extraire les couleurs à des positions différentes dans le temps.</p>\n<div class=\"gatsby-highlight\" data-language=\"glsl\"><pre class=\"language-glsl\"><code class=\"language-glsl\">fixed4 mainCol <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_MainTex<span class=\"token punctuation\">,</span> i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\n<span class=\"token comment\">// glitch 1</span>\nfloat2 offsetTexCoord <span class=\"token operator\">=</span> <span class=\"token function\">float2</span><span class=\"token punctuation\">(</span>\n    i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">.</span>x<span class=\"token punctuation\">,</span>\n    <span class=\"token function\">frac</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">.</span>y <span class=\"token operator\">+</span> _Time<span class=\"token punctuation\">.</span>y <span class=\"token operator\">*</span> <span class=\"token number\">0.33</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nfixed4 glitchCol <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_GlitchTex<span class=\"token punctuation\">,</span> offsetTexCoord<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// glitch 2</span>\nfloat2 offsetTexCoord2 <span class=\"token operator\">=</span> <span class=\"token function\">float2</span><span class=\"token punctuation\">(</span>\n    i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">.</span>x<span class=\"token punctuation\">,</span>\n    <span class=\"token function\">frac</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">.</span>y <span class=\"token operator\">+</span>  _Time<span class=\"token punctuation\">.</span>y <span class=\"token operator\">*</span> <span class=\"token number\">0.4521</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nfixed4 glitchCol2 <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_GlitchTex<span class=\"token punctuation\">,</span> offsetTexCoord2<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n<span class=\"token comment\">// glitch 3</span>\nfloat2 offsetTexCoord3 <span class=\"token operator\">=</span> <span class=\"token function\">float2</span><span class=\"token punctuation\">(</span>\n    i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">.</span>x<span class=\"token punctuation\">,</span>\n    <span class=\"token function\">frac</span><span class=\"token punctuation\">(</span>i<span class=\"token punctuation\">.</span>texcoord<span class=\"token punctuation\">.</span>y <span class=\"token operator\">+</span> _Time<span class=\"token punctuation\">.</span>y <span class=\"token operator\">*</span> <span class=\"token number\">0.2541</span><span class=\"token punctuation\">)</span>\n<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\nfixed4 glitchCol3 <span class=\"token operator\">=</span> <span class=\"token function\">tex2D</span><span class=\"token punctuation\">(</span>_GlitchTex<span class=\"token punctuation\">,</span> offsetTexCoord3<span class=\"token punctuation\">)</span><span class=\"token punctuation\">;</span>\n\nfixed4 col <span class=\"token operator\">=</span> mainCol <span class=\"token operator\">+</span> mainCol <span class=\"token operator\">*</span> glitchCol <span class=\"token operator\">*</span> <span class=\"token number\">0.4</span> <span class=\"token operator\">+</span> mainCol <span class=\"token operator\">*</span> glitchCol2 <span class=\"token operator\">*</span> <span class=\"token number\">0.2</span> <span class=\"token operator\">+</span> mainCol <span class=\"token operator\">*</span> glitchCol3 <span class=\"token operator\">*</span> <span class=\"token number\">0.4</span><span class=\"token punctuation\">;</span></code></pre></div>\n<p>Le résultat :</p>\n<div style=\"text-align:center\">\n<video autoplay=\"autoplay\" loop=\"loop\" width=\"320\" height=\"320\">\n    <source src=\"/8d8caa899b6929ed5686da0b93353d02/test5.mp4\" type=\"video/mp4\" />\n</video>\n</div>\n<p>Ici le shader va lire dans la texture à 3 positions différentes, chacune de ces positions défilant à une vitesse différente. Ensuite, on additionne toutes les couleurs obtenues mais en appliquant une constante pour adoucir le rendu (sinon le rendu est trop lumineux). Autre conséquence, le rendu animé ne peut plus boucler de façon fluide comme avant, car il est extrêmement rare que les 3 couches de glitch retrouvent leur position initiale au même moment. Ainsi, dans le jeu, is smeble que l’animation ne se répête jamais ce qui la rends plus intéressante à regarder.</p>\n<h3 id=\"we-need-to-go-deeper-again-nous-devons-aller-encore-plus-loin\" style=\"position:relative;\"><a href=\"#we-need-to-go-deeper-again-nous-devons-aller-encore-plus-loin\" aria-label=\"we need to go deeper again nous devons aller encore plus loin permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>We need to go deeper AGAIN (Nous devons aller ENCORE plus loin)</h3>\n<p>On pourrait s’arrêter là, mais mon cerveau n’est pas encore satisfait. On observe encore certains motifs, il y a mieux à faire.</p>\n<p>L’idée en bref : plutôt que d’additionner les couleurs des 3 couches, multiplions les ! En effet, il y a toujours une valeur lumineuse “minimale” (qu’on visualise comme une bande blanche) que l’œil peut suivre le long du chemin et qui se répétera. Le fait que les lignes se croisent rend le suivi plus difficile mais pas impossible.<br>\nAlors qu’en multipliant les 3 valeurs, parfois les lignes se chevaucheront et créeront des lignes plus brillantes, et parfois elles s’éloigneront et les lignes disparaitront en fondu.</p>\n<p>Niveau maths le changement est assez direct :</p>\n<div class=\"gatsby-highlight\" data-language=\"glsl\"><pre class=\"language-glsl\"><code class=\"language-glsl\">fixed4 col <span class=\"token operator\">=</span> mainCol <span class=\"token operator\">+</span> mainCol <span class=\"token operator\">*</span> glitchCol <span class=\"token operator\">*</span> glitchCol2 <span class=\"token operator\">*</span> glitchCol3<span class=\"token punctuation\">;</span></code></pre></div>\n<p>Par contre il est nécessaire de revoir la texutre pour qu’elle soutienne l’idée. Pour que le rendu soit intéressant il faut que les lignes se superposent plus souvent (lignes plus larges, luminosité plus claire). En repartant de la texture précédente, j’ai inversé les couleurs puis manipulé la courbe de luminosité jusqu’à ce que le rendu me plaise.</p>\n<p><span\n      class=\"gatsby-resp-image-wrapper\"\n      style=\"position: relative; display: block; margin-left: auto; margin-right: auto; max-width: 590px; \"\n    >\n      <a\n    class=\"gatsby-resp-image-link\"\n    href=\"/static/9a7a6cc1c105cd1ca473eadc46ed386d/2bef9/lightdust2.png\"\n    style=\"display: block\"\n    target=\"_blank\"\n    rel=\"noopener\"\n  >\n    <span\n    class=\"gatsby-resp-image-background-image\"\n    style=\"padding-bottom: 100%; position: relative; bottom: 0; left: 0; background-image: url('data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABQAAAAUCAYAAACNiR0NAAAACXBIWXMAAC4fAAAuHwF47oFfAAAAa0lEQVQ4y63TMQ0AIQBD0SpiuAkSZCABE7AhgbBcDgcEjz0Tf3gCfppqjGGSeu8mKYRgkuacJqnWapJyzibpfV+T+OQYo0n6vs8klVJMUkrJJN17TdJayyQ9z2OSWmsm6ZxjEj8Kfr29t0k/ZVanzn4iXgEAAAAASUVORK5CYII='); background-size: cover; display: block;\"\n  ></span>\n  <img\n        class=\"gatsby-resp-image-image\"\n        alt=\"lightdust2\"\n        title=\"lightdust2\"\n        src=\"/static/9a7a6cc1c105cd1ca473eadc46ed386d/fcda8/lightdust2.png\"\n        srcset=\"/static/9a7a6cc1c105cd1ca473eadc46ed386d/12f09/lightdust2.png 148w,\n/static/9a7a6cc1c105cd1ca473eadc46ed386d/e4a3f/lightdust2.png 295w,\n/static/9a7a6cc1c105cd1ca473eadc46ed386d/fcda8/lightdust2.png 590w,\n/static/9a7a6cc1c105cd1ca473eadc46ed386d/efc66/lightdust2.png 885w,\n/static/9a7a6cc1c105cd1ca473eadc46ed386d/2bef9/lightdust2.png 1024w\"\n        sizes=\"(max-width: 590px) 100vw, 590px\"\n        style=\"width:100%;height:100%;margin:0;vertical-align:middle;position:absolute;top:0;left:0;\"\n        loading=\"lazy\"\n      />\n  </a>\n    </span></p>\n<p>Et voilà le résultat final :</p>\n<div style=\"text-align:center\">\n<video autoplay=\"autoplay\" loop=\"loop\" width=\"320\" height=\"320\">\n    <source src=\"/1e21a8b71d904eb4d8c1316559f078e5/test6.mp4\" type=\"video/mp4\" />\n</video>\n</div>\n<p>Comme vous pouvez le voir, parfois les lignes apparaissent puis s’estompent. Si vous êtes arrivés jusque là dans votre implémentation vous pouvez constater que les lignes apparaissent et disparaissent à des endroits qui semblent toujours différents, et on peut l’observer pendant des heures sans trouver de répétition dans les motifs. L’effet est maintenant plus subtil, plus intrigant !</p>\n<h2 id=\"mots-de-la-fin\" style=\"position:relative;\"><a href=\"#mots-de-la-fin\" aria-label=\"mots de la fin permalink\" class=\"anchor before\"><svg aria-hidden=\"true\" focusable=\"false\" height=\"16\" version=\"1.1\" viewBox=\"0 0 16 16\" width=\"16\"><path fill-rule=\"evenodd\" d=\"M4 9h1v1H4c-1.5 0-3-1.69-3-3.5S2.55 3 4 3h4c1.45 0 3 1.69 3 3.5 0 1.41-.91 2.72-2 3.25V8.59c.58-.45 1-1.27 1-2.09C10 5.22 8.98 4 8 4H4c-.98 0-2 1.22-2 2.5S3 9 4 9zm9-3h-1v1h1c1 0 2 1.22 2 2.5S13.98 12 13 12H9c-.98 0-2-1.22-2-2.5 0-.83.42-1.64 1-2.09V6.25c-1.09.53-2 1.84-2 3.25C6 11.31 7.55 13 9 13h4c1.45 0 3-1.69 3-3.5S14.5 6 13 6z\"></path></svg></a>Mots de la fin</h2>\n<p>Merci de m’avoir suivi jusque là ! Je travaille dur sur <a href=\"https://a-time-paradox.com/\">A Time Paradox</a> pour que le rendu soit cool ! Passez voir le site !</p>\n<p>Vous souhaitez régir ? Vous avez fait des choses grace à cet article ? dites-le moi !<br>\nEnvoyez vos messages privés et mentions sur twitter <a href=\"https://twitter.com/lythom\">@Lythom</a>, et les messages à <a href=\"mailto:samuel@a-game-studio.com\">samuel@a-game-studio.com</a>. Je les retweeterai !</p>\n<p>Bon hacking !</p>","frontmatter":{"title":"Trafiquer un shader","date":"2018-08-27","description":"Apprenez à programmer un effet visuel attrayant grace aux shaders."}}},"pageContext":{"lang":"fr","slug":"/fr/blog/hacking-through-shaders/","previous":{"fields":{"slug":"/fr/projects/a-time-paradox/"},"frontmatter":{"title":"A Time Paradox"}},"next":{"fields":{"slug":"/fr/blog/what-babies-teach-us-about-game-design/"},"frontmatter":{"title":"Ce que les bébés nous apprennent sur le game design"}}}}}