{"id":2735,"date":"2015-06-11T09:04:35","date_gmt":"2015-06-11T09:04:35","guid":{"rendered":"http:\/\/anthroponaute.fr\/blog-informatique\/?p=2735"},"modified":"2020-02-04T09:06:51","modified_gmt":"2020-02-04T09:06:51","slug":"calculer-les-tangentes-et-binormales","status":"publish","type":"post","link":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/?p=2735","title":{"rendered":"Calculer la tangente et la bitangente d&rsquo;une face"},"content":{"rendered":"<p><a href=\"https:\/\/anthropoya.cluster014.ovh.net\/blog-informatique\/wp-content\/uploads\/2015\/06\/NTBFromUVs_cadre1.png\"><img decoding=\"async\" loading=\"lazy\" class=\"alignnone size-full wp-image-2750\" src=\"https:\/\/anthropoya.cluster014.ovh.net\/blog-informatique\/wp-content\/uploads\/2015\/06\/NTBFromUVs_cadre1.png\" alt=\"NTBFromUVs_cadre\" width=\"480\" height=\"270\" srcset=\"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/wp-content\/uploads\/2015\/06\/NTBFromUVs_cadre1.png 480w, https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/wp-content\/uploads\/2015\/06\/NTBFromUVs_cadre1-300x169.png 300w\" sizes=\"(max-width: 480px) 100vw, 480px\" \/><\/a><\/p>\n<p><strong>Intro : <\/strong><\/p>\n<p>Pour certains algorithmes de rendu 3D par shader (comme celui du <strong>normal mapping<\/strong>) nous avons besoin, en plus de la normale, de deux vecteurs <strong>perpendiculaires<\/strong> \u00e0 celle-ci : ce sont la <strong>tangente<\/strong> et la <strong>bitangente<\/strong> (<em>ou binormale<\/em>).<\/p>\n<p>Voici <strong>trois m\u00e9thode<\/strong> pour les <strong>obtenir<\/strong> et les calculer.<\/p>\n<p><strong>Explications :<\/strong><\/p>\n<p>Math\u00e9matiquement, le calcul de ces <strong>deux autres composantes<\/strong> autres que la normale s&rsquo;\u00e9nonce ainsi :<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec%7BEdge1%7D+%3D+%5Cvec%7BV%7D_2+-+%5Cvec%7BV%7D_1+&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='\\vec{Edge1} = \\vec{V}_2 - \\vec{V}_1 ' title='\\vec{Edge1} = \\vec{V}_2 - \\vec{V}_1 ' class='latex' \/>\n<p>&nbsp;<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec%7BEdge2%7D+%3D+%5Cvec%7BV%7D_3+-+%5Cvec%7BV%7D_1+&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='\\vec{Edge2} = \\vec{V}_3 - \\vec{V}_1 ' title='\\vec{Edge2} = \\vec{V}_3 - \\vec{V}_1 ' class='latex' \/>\n<p>&nbsp;<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec%7BUVEdge1%7D+%3D+%5Cvec%7BUV%7D_2+-+%5Cvec%7BUV%7D_1+&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='\\vec{UVEdge1} = \\vec{UV}_2 - \\vec{UV}_1 ' title='\\vec{UVEdge1} = \\vec{UV}_2 - \\vec{UV}_1 ' class='latex' \/>\n<p>&nbsp;<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec%7BUVEdge2%7D+%3D+%5Cvec%7BUV%7D_3+-+%5Cvec%7BUV%7D_1+&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='\\vec{UVEdge2} = \\vec{UV}_3 - \\vec{UV}_1 ' title='\\vec{UVEdge2} = \\vec{UV}_3 - \\vec{UV}_1 ' class='latex' \/>\n<p>&nbsp;<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=p+%3D+%28%5Cvec%7BUVEdge1%7D_y+%2A+%5Cvec%7BUVEdge2%7D_x%29+-+%5Cnewline+%28%5Cvec%7BUVEdge1%7D_x+%2A+%5Cvec%7BUVEdge2%7D_y%29+&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='p = (\\vec{UVEdge1}_y * \\vec{UVEdge2}_x) - \\newline (\\vec{UVEdge1}_x * \\vec{UVEdge2}_y) ' title='p = (\\vec{UVEdge1}_y * \\vec{UVEdge2}_x) - \\newline (\\vec{UVEdge1}_x * \\vec{UVEdge2}_y) ' class='latex' \/>\n<p>&nbsp;<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=c+%3D+1+%2F+p+&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='c = 1 \/ p ' title='c = 1 \/ p ' class='latex' \/>\n<p>&nbsp;<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec%7BTangent%7D+%3D+%5B%5Censpace+%28%5Cvec%7BEdge1%7D+%2A+-%5Cvec%7BUVEdge2%7D_y%29+%2B+%28%5Cvec%7BEdge2%7D+%2A+%5Cvec%7BUVEdge1%7D_y%29+%5Censpace+%5D%5Cnewline+%2A+c+&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='\\vec{Tangent} = [\\enspace (\\vec{Edge1} * -\\vec{UVEdge2}_y) + (\\vec{Edge2} * \\vec{UVEdge1}_y) \\enspace ]\\newline * c ' title='\\vec{Tangent} = [\\enspace (\\vec{Edge1} * -\\vec{UVEdge2}_y) + (\\vec{Edge2} * \\vec{UVEdge1}_y) \\enspace ]\\newline * c ' class='latex' \/>\n<p>&nbsp;<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cvec%7BBitangent%7D+%3D+%5B%5Censpace%28%5Cvec%7BEdge1%7D+%2A+-%5Cvec%7BUVEdge2%7D_x%29+%2B+%28%5Cvec%7BEdge2%7D+%2A+%5Cvec%7BUVEdge1%7D_x%29%5Censpace%5D+%2A+c+&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='\\vec{Bitangent} = [\\enspace(\\vec{Edge1} * -\\vec{UVEdge2}_x) + (\\vec{Edge2} * \\vec{UVEdge1}_x)\\enspace] * c ' title='\\vec{Bitangent} = [\\enspace(\\vec{Edge1} * -\\vec{UVEdge2}_x) + (\\vec{Edge2} * \\vec{UVEdge1}_x)\\enspace] * c ' class='latex' \/>\n<p>&nbsp;<\/p>\n<p>Je vous montre <strong>une fonction<\/strong> permettant de calculer la <em>tangente<\/em> et la <em>bitangente<\/em>.<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\/* P1, P2, P3 repr\u00e9sentent les points d'une face donn\u00e9e\r\n   UV1, UV2, UV2 repr\u00e9sentent les coordonn\u00e9es de la texture de cette derni\u00e8re face\r\n*\/\r\nvoid ComputeTangentAndBinormal(const D3DXVECTOR3&amp; P1, const D3DXVECTOR3&amp; P2,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0       const D3DXVECTOR3&amp; P3, const D3DXVECTOR2&amp; UV1,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0       const D3DXVECTOR2&amp; UV2, const D3DXVECTOR2&amp; UV3,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0       D3DXVECTOR3&amp; tangent, D3DXVECTOR3&amp; bitangent)\r\n{\r\n\u00a0\u00a0 D3DXVECTOR3 Edge1 = P2 - P1;\r\n\u00a0\u00a0 D3DXVECTOR3 Edge2 = P3 - P1;\r\n\u00a0\u00a0 D3DXVECTOR2 Edge1uv = UV2 - UV1;\r\n\u00a0\u00a0 D3DXVECTOR2 Edge2uv = UV3 - UV1;\r\n\r\n\u00a0\u00a0 float cp = Edge1uv.y * Edge2uv.x - Edge1uv.x * Edge2uv.y;\r\n\r\n\u00a0\u00a0 if (cp != 0.0f)\r\n\u00a0\u00a0 {\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 float mul = 1.0f \/ cp;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 Tangent\u00a0\u00a0 = (Edge1 * -Edge2uv.y + Edge2 * Edge1uv.y) * mul;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 Bitangent = (Edge1 * -Edge2uv.x + Edge2 * Edge1uv.x) * mul;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 D3DXVEC3Normalize(&amp;Tangent, &amp;Tangent);\u00a0\u00a0 \u00a0\u00a0\u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0 D3DXVEC3Normalize(&amp;Bitangent, &amp;Bitangent); \u00a0\r\n\u00a0\u00a0 }\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Un autre algorithme est disponible si vous ne voulez <strong>pas calculer<\/strong> les donn\u00e9es <strong>face par face<\/strong> !<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\n\/* Ceci est la structure d'un vertex en m\u00e9moire vid\u00e9o *\/\r\nstruct PTVertex\r\n{\r\n\u00a0\u00a0 \u00a0D3DXVECTOR3 position;\r\n\u00a0\u00a0 \u00a0D3DXVECTOR2 texture;\r\n}\r\n\r\n\/* Cette fonction prend en param\u00e8tres le tableau des vertices\r\n   d'un mod\u00e8le donn\u00e9.\r\n   Elle prend aussi l'index courant de la face en question\r\n   (premier vertex de celle-ci)\r\n*\/\r\nvoid ComputeTBN_Vectors(PTVertex* vertices,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0 uint32 index,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0 D3DXVECTOR3&amp; v3Tangent,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0 D3DXVECTOR3&amp; v3Binormal,\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0 D3DXVECTOR3&amp; v3Normal)\r\n{\r\n\u00a0\u00a0 \u00a0if (index &lt; 0 || vertices == nullptr)\r\n\u00a0\u00a0 \u00a0{\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0return;\r\n\u00a0\u00a0 \u00a0}\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0 \u00a0D3DXVECTOR3 edge1;\r\n\u00a0\u00a0 \u00a0D3DXVECTOR3 edge2;\r\n\r\n\u00a0\u00a0 \u00a0D3DXVECTOR2 tuVector;\r\n\u00a0\u00a0 \u00a0D3DXVECTOR2 tvVector;\r\n\r\n\u00a0\u00a0 \u00a0PTVertex vertex1 = &amp;vertices[index];\r\n\u00a0\u00a0 \u00a0index++;\r\n\r\n\u00a0\u00a0 \u00a0PTVertex vertex2 = &amp;vertices[index];\r\n\u00a0\u00a0 \u00a0index++;\r\n\r\n\u00a0\u00a0 \u00a0PTVertex vertex3 = &amp;vertices[index];\r\n\u00a0\u00a0 \u00a0index++;\r\n\r\n\u00a0\u00a0 \u00a0edge1 = vertex2-&gt;position - vertex1-&gt;position;\r\n\u00a0\u00a0 \u00a0edge2 = vertex3-&gt;position - vertex1-&gt;position;\r\n\r\n\u00a0\u00a0 \u00a0tuVector.x = vertex2-&gt;texture.x - vertex1-&gt;texture.x;\r\n\u00a0\u00a0 \u00a0tvVector.x = vertex2-&gt;texture.y - vertex1-&gt;texture.y;\r\n\r\n\u00a0\u00a0 \u00a0tuVector.y = vertex3-&gt;texture.x - vertex1-&gt;texture.x;\r\n\u00a0\u00a0 \u00a0tvVector.y = vertex3-&gt;texture.y - vertex1-&gt;texture.y;\r\n\r\n\u00a0\u00a0 \u00a0float den = 1.0f \/ (tuVector.x * tvVector.y - tuVector.y * tvVector.x);\r\n\r\n\u00a0\u00a0 \u00a0tangent = (edge1 * tvVector.y - edge2 * tvVector.x) * den;\r\n\u00a0\u00a0 \u00a0binormal = (edge2 * tuVector.x - edge1 * tuVector.y) * den;\r\n\r\n\u00a0\u00a0 \u00a0D3DXVec3Normalize(&amp;tangent, &amp;tangent);\r\n\u00a0\u00a0 \u00a0D3DXVec3Normalize(&amp;binormal, &amp;binormal);\r\n\r\n    D3DXVECTOR3 normal;\r\n\u00a0\u00a0 \u00a0D3DXVec3Cross(&amp;normal, &amp;tangent, &amp;binormal);\r\n\u00a0\u00a0 \u00a0D3DXVec3Normalize(&amp;normal, &amp;normal);\r\n\r\n\u00a0\u00a0 \u00a0v3Tangent = tangent;\r\n\u00a0\u00a0 \u00a0v3Binormal = binormal;\r\n    v3Normal = normal;\r\n}\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Voici la <strong>troisi\u00e8me<\/strong> fonction (sans doute la meilleure) :<\/p>\n<pre class=\"brush: cpp; title: ; notranslate\" title=\"\">\r\nvoid ComputeTangentBasis(\r\n\u00a0\u00a0 \u00a0\/\/ Entr\u00e9es\r\n\u00a0\u00a0 \u00a0const std::vector&lt;D3DXVECTOR3&gt;&amp; vertices,\r\n\u00a0\u00a0 \u00a0const std::vector&lt;D3DXVECTOR2&gt;&amp; uvs,\r\n\u00a0\u00a0 \u00a0\/\/ Sorties\r\n\u00a0\u00a0 \u00a0std::vector&lt;D3DXVECTOR3&gt;&amp; tangents,\r\n\u00a0\u00a0 \u00a0std::vector&lt;D3DXVECTOR3&gt;&amp; bitangents\r\n)\r\n{\r\n\u00a0\u00a0\u00a0 for (int i = 0; i &lt; vertices.size(); i += 3)\r\n\u00a0\u00a0 \u00a0{\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Les vertices\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 const D3DXVECTOR3&amp; v0 = vertices[i + 0];\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 const D3DXVECTOR3&amp; v1 = vertices[i + 1];\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0const D3DXVECTOR3&amp; v2 = vertices[i + 2];\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Les coordonn\u00e9es des textures\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 const D3DXVECTOR2&amp; uv0 = uvs[i + 0];\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 const D3DXVECTOR2&amp; uv1 = uvs[i + 1];\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0  const D3DXVECTOR2&amp; uv2 = uvs[i + 2];\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Les c\u00f4t\u00e9s du triangle : &quot;position delta&quot;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 D3DXVECTOR3 deltaPos1 = v1 - v0;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 D3DXVECTOR3 deltaPos2 = v2 - v0;\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ UV delta\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 D3DXVECTOR2 deltaUV1 = uv1 - uv0;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 D3DXVECTOR2 deltaUV2 = uv2 - uv0;\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 float r = 1.0f \/ (deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 D3DXVECTOR3 tangent = (deltaPos1 * deltaUV2.y\u00a0\u00a0 - deltaPos2 * deltaUV1.y) * r;\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 D3DXVECTOR3 bitangent = (deltaPos2 * deltaUV1.x\u00a0\u00a0 - deltaPos1 * deltaUV2.x) * r;\r\n\r\n\u00a0\u00a0 \u00a0\u00a0\u00a0 \u00a0\/\/ Assigne la m\u00eame tangente pour les trois vertex en question\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tangents.push_back(tangent);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tangents.push_back(tangent);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 tangents.push_back(tangent);\r\n\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 \/\/ Pareil pour les binormales \/ bitangentes\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 bitangents.push_back(bitangent);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 bitangents.push_back(bitangent);\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 bitangents.push_back(bitangent);\r\n\u00a0\u00a0 \u00a0}\r\n}\r\n\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>Voil\u00e0 c&rsquo;est tout pour les algorithmes !<\/p>\n<p>Sachez que comme vous l&rsquo;avez vu, la <strong>m\u00e9thode<\/strong> standard indique que la tangente doit \u00eatre orient\u00e9e dans <strong>la m\u00eame direction<\/strong> que les <strong>coordonn\u00e9es de texture<\/strong> du triangle en question.<\/p>\n<p>D&rsquo;autre part ce n&rsquo;est pas l&rsquo;objet de cet article, mais je vous apprend que la <em>normale<\/em>, la <em>binormale<\/em> et la <em>tangente<\/em> sont trois vecteurs qui forment une <em><strong>base <\/strong><\/em>permettant de <strong>transformer les<\/strong> <strong>normales<\/strong> issues (et extraites) d&rsquo;une <strong>image RGB<\/strong> sp\u00e9ciale VERS l&rsquo;espace \/ coordonn\u00e9es du mod\u00e8le du mesh contenant les triangles (<em>bind space<\/em> ou <em>model space<\/em> en anglais).<\/p>\n<p>Cette base est repr\u00e9sent\u00e9e math\u00e9matiquement par la matrice suivante :<\/p>\n<img src='https:\/\/s0.wp.com\/latex.php?latex=%5Cbegin%7Bbmatrix%7D+%5Ctextbf%7BT%7D_x+%26+%5Ctextbf%7BB%7D_x+%26+%5Ctextbf%7BN%7D_x+%5C%5C+%5Ctextbf%7BT%7D_y+%26+%5Ctextbf%7BB%7D_y+%26+%5Ctextbf%7BN%7D_y+%5C%5C+%5Ctextbf%7BT%7D_z+%26+%5Ctextbf%7BB%7D_z+%26+%5Ctextbf%7BN%7D_z+%5Cend%7Bbmatrix%7D+&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='\\begin{bmatrix} \\textbf{T}_x &amp; \\textbf{B}_x &amp; \\textbf{N}_x \\\\ \\textbf{T}_y &amp; \\textbf{B}_y &amp; \\textbf{N}_y \\\\ \\textbf{T}_z &amp; \\textbf{B}_z &amp; \\textbf{N}_z \\end{bmatrix} ' title='\\begin{bmatrix} \\textbf{T}_x &amp; \\textbf{B}_x &amp; \\textbf{N}_x \\\\ \\textbf{T}_y &amp; \\textbf{B}_y &amp; \\textbf{N}_y \\\\ \\textbf{T}_z &amp; \\textbf{B}_z &amp; \\textbf{N}_z \\end{bmatrix} ' class='latex' \/>\n<p>&nbsp;<\/p>\n<p><img src='https:\/\/s0.wp.com\/latex.php?latex=%5Ctextbf%7BT%7D+&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='\\textbf{T} ' title='\\textbf{T} ' class='latex' \/> repr\u00e9sentant la <em>tangente<\/em>. <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Ctextbf%7BB%7D+&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='\\textbf{B} ' title='\\textbf{B} ' class='latex' \/> repr\u00e9sentant la <em>binormale<\/em>. <img src='https:\/\/s0.wp.com\/latex.php?latex=%5Ctextbf%7BN%7D+&#038;bg=ffffff&#038;fg=000000&#038;s=2' alt='\\textbf{N} ' title='\\textbf{N} ' class='latex' \/> repr\u00e9sentant la <em>normale<\/em>.<\/p>\n<p>Il ne reste plus qu&rsquo;\u00e0 multiplier le <strong>vecteur normal<\/strong> par cette matrice est le tour est jou\u00e9 !<\/p>\n<p>&nbsp;<\/p>\n<p><strong>R\u00e9sum\u00e9 :<\/strong><\/p>\n<p>Nous avons pr\u00e9sent\u00e9 l\u2019algorithme permettant de calculer les <em>binormales<\/em> et les <em>bitangentes<\/em> en utilisant les <strong>coordonn\u00e9es des textures<\/strong> du <em>mesh<\/em> en question.<\/p>\n<p><strong>R\u00e9f\u00e9rences :<\/strong><\/p>\n<p>&#8211; http:\/\/www.3dkingdoms.com\/weekly\/weekly.php?a=37<\/p>\n<p>&#8211; http:\/\/www.opengl-tutorial.org\/intermediate-tutorials\/tutorial-13-normal-mapping\/<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Intro : Pour certains algorithmes de rendu 3D par shader (comme celui du normal mapping) nous avons besoin, en plus de la normale, de deux vecteurs perpendiculaires \u00e0 celle-ci : ce sont la tangente et la bitangente (ou binormale). Voici trois m\u00e9thode pour les obtenir et les calculer. Explications : Math\u00e9matiquement, le calcul de ces [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[6],"tags":[],"_links":{"self":[{"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/posts\/2735"}],"collection":[{"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=2735"}],"version-history":[{"count":119,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/posts\/2735\/revisions"}],"predecessor-version":[{"id":5887,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=\/wp\/v2\/posts\/2735\/revisions\/5887"}],"wp:attachment":[{"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=2735"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=2735"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.la-porte-des-nebuleuses.net\/blog-informatique\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=2735"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}