{"id":469,"date":"2022-02-03T22:02:22","date_gmt":"2022-02-03T14:02:22","guid":{"rendered":"http:\/\/liyanliang.net\/?p=469"},"modified":"2022-02-03T22:41:47","modified_gmt":"2022-02-03T14:41:47","slug":"normal-mapping","status":"publish","type":"post","link":"http:\/\/liyanliang.net\/index.php\/2022\/02\/03\/normal-mapping\/","title":{"rendered":"OpenGL-\u6cd5\u7ebf\u8d34\u56fe(Normal Mapping)"},"content":{"rendered":"\n<p><strong>\u80cc\u666f<\/strong><\/p>\n\n\n\n<p>\u5728\u4e00\u4e2a\u5e73\u9762\u4e0a\u5982\u679c\u53ea\u6709\u4e00\u4e2a\u6cd5\u7ebf\uff0c\u6574\u4e2a\u9762\u7684\u5149\u7167\u5f3a\u5ea6\u90fd\u662f\u76f8\u540c\u7684\uff0c\u5982\u679c\u662f\u51f9\u51f8\u7684\u8868\u9762\uff0c\u65e0\u6cd5\u8868\u73b0\u8868\u9762\u7684\u771f\u662f\u5149\u7167\u6548\u679c\uff0c\u6240\u4ee5\u5f15\u5165\u4e86\u6cd5\u7ebf\u8d34\u56fe\u3002\u5e73\u9762\u5185\u7684\u6bcf\u4e00\u4e2afragment\u90fd\u5b58\u50a8\u4e00\u4e2a\u6cd5\u7ebf\u5411\u91cf\uff0c\u901a\u8fc7\u6cd5\u7ebf\u5411\u91cf\u8ba1\u7b97\u5207\u7ebf\u5411\u91cf\u548c\u526f\u5207\u5411\u5411\u91cf\u3002<\/p>\n\n\n\n<p>\u5df2\u77e5\u4e0a\u5411\u91cf\u662f\u8868\u9762\u7684\u6cd5\u7ebf\u5411\u91cf\u3002\u53f3\u548c\u524d\u5411\u91cf\u662f\u5207\u7ebf(Tagent)\u548c\u526f\u5207\u7ebf(Bitangent)\u5411\u91cf\u3002\u4e0b\u9762\u7684\u56fe\u7247\u5c55\u793a\u4e86\u4e00\u4e2a\u8868\u9762\u7684\u4e09\u4e2a\u5411\u91cf\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-image is-style-default\"><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/20220203214551.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><strong>\u8ba1\u7b97\u539f\u7406<\/strong><\/p>\n\n\n\n<p>\u8ba1\u7b97\u6bcf\u4e2a\u8868\u9762\u7684\u5207\u7ebf\u548c\u526f\u5207\u7ebf\u53ef\u4ee5\u53c2\u7167<a href=\"https:\/\/learnopengl-cn.github.io\/05%20Advanced%20Lighting\/04%20Normal%20Mapping\/\">https:\/\/learnopengl-cn.github.io\/<\/a>\uff0c\u4e3b\u8981\u8ba1\u7b97\u8fc7\u7a0b\u5982\u4e0b\uff1a<\/p>\n\n\n\n<figure class=\"wp-block-image is-style-default\"><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/20220203214857.png\" alt=\"\"\/><\/figure>\n\n\n\n<figure class=\"wp-block-image is-style-default\"><img decoding=\"async\" src=\"https:\/\/liyanliangpublic.oss-cn-hongkong.aliyuncs.com\/img\/20220203214925.png\" alt=\"\"\/><\/figure>\n\n\n\n<p><strong>\u9876\u70b9\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">   &nbsp; &nbsp; &nbsp; V3N3UV2 &nbsp;verts[] =<br>   &nbsp; &nbsp; &nbsp;  {<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, -0.5f, &nbsp;0.5f , &nbsp;1.0, 0.0, 0.0, 0.0f, 0.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, -0.5f, -0.5f , &nbsp;1.0, 0.0, 0.0, 1.0f, 0.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, &nbsp;0.5f, -0.5f , &nbsp;1.0, 0.0, 0.0, 1.0f, 1.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, &nbsp;0.5f, -0.5f , &nbsp;1.0, 0.0, 0.0, 1.0f, 1.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, &nbsp;0.5f, &nbsp;0.5f , &nbsp;1.0, 0.0, 0.0, 0.0f, 1.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, -0.5f, &nbsp;0.5f , &nbsp;1.0, 0.0, 0.0, 0.0f, 0.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, -0.5f, -0.5f , &nbsp;-1.0, 0.0,0.0, 0.0f, 0.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, -0.5f, &nbsp;0.5f , &nbsp;-1.0, 0.0,0.0, 1.0f, 0.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, &nbsp;0.5f, &nbsp;0.5f , &nbsp;-1.0, 0.0,0.0, 1.0f, 1.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, &nbsp;0.5f, &nbsp;0.5f , &nbsp;-1.0, 0.0,0.0, 1.0f, 1.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, &nbsp;0.5f, -0.5f , &nbsp;-1.0, 0.0,0.0, 0.0f, 1.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, -0.5f, -0.5f , &nbsp;-1.0, 0.0,0.0, 0.0f, 0.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, &nbsp;0.5f, &nbsp;0.5f , &nbsp;-0.0, 1.0,0.0, 1.0f, 0.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, &nbsp;0.5f, &nbsp;0.5f , &nbsp;-0.0, 1.0,0.0, 0.0f, 0.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, &nbsp;0.5f, -0.5f , &nbsp;-0.0, 1.0,0.0, 0.0f, 1.0f  },<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, &nbsp;0.5f, -0.5f , &nbsp;0.0, 1.0,0.0, 0.0f, 1.0f &nbsp; },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, &nbsp;0.5f, -0.5f , &nbsp;0.0, 1.0,0.0, 1.0f, 1.0f &nbsp; },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, &nbsp;0.5f, &nbsp;0.5f , &nbsp;0.0, 1.0,0.0, 1.0f, 0.0f &nbsp; },<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, -0.5f, -0.5f , &nbsp;0.0, -1.0,0.0, 1.0f, 0.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, -0.5f, -0.5f , &nbsp;0.0, -1.0,0.0, 0.0f, 0.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, -0.5f, &nbsp;0.5f , &nbsp;0.0, -1.0,0.0, 0.0f, 1.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, -0.5f, &nbsp;0.5f , &nbsp;0.0, -1.0,0.0, 0.0f, 1.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, -0.5f, &nbsp;0.5f , &nbsp;0.0, -1.0,0.0, 1.0f, 1.0f  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, -0.5f, -0.5f , &nbsp;0.0, -1.0,0.0, 1.0f, 0.0f  },<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, -0.5f, &nbsp;0.5f, &nbsp; 0.0, 0.0, 1.0, &nbsp;0.0f, 0.0f },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, -0.5f, &nbsp;0.5f, &nbsp; 0.0, 0.0, 1.0, &nbsp;1.0f, 0.0f },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, &nbsp;0.5f, &nbsp;0.5f, &nbsp; 0.0, 0.0, 1.0, &nbsp;1.0f, 1.0f },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, &nbsp;0.5f, &nbsp;0.5f, &nbsp; 0.0, 0.0, 1.0, &nbsp;1.0f, 1.0f },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, &nbsp;0.5f, &nbsp;0.5f, &nbsp; 0.0, 0.0, 1.0, &nbsp;0.0f, 1.0f },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, -0.5f, &nbsp;0.5f, &nbsp; 0.0, 0.0, 1.0, &nbsp;0.0f, 0.0f },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, -0.5f, -0.5f, &nbsp; 0.0, 0.0,-1.0, &nbsp;0.0f, 0.0f },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, -0.5f, -0.5f, &nbsp; 0.0, 0.0,-1.0, &nbsp;1.0f, 0.0f },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, &nbsp;0.5f, -0.5f, &nbsp; 0.0, 0.0,-1.0, &nbsp;1.0f, 1.0f },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  {-0.5f, &nbsp;0.5f, -0.5f, &nbsp; 0.0, 0.0,-1.0, &nbsp;1.0f, 1.0  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, &nbsp;0.5f, -0.5f, &nbsp; 0.0, 0.0,-1.0, &nbsp;0.0f, 1.0  },<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  { 0.5f, -0.5f, -0.5f, &nbsp; 0.0, 0.0,-1.0, &nbsp;0.0f, 0.0  },<br>   &nbsp; &nbsp; &nbsp;  };<\/pre>\n\n\n\n<p><strong>\u5207\u7ebf\u4e0e\u526f\u5207\u7ebf\u8ba1\u7b97<\/strong>\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">   &nbsp; void convertTBN(V3N3UV2* vertices,NORMALMAP* nmVerts)<br>   &nbsp;  {<br>   &nbsp; &nbsp; &nbsp; &nbsp;for (size_t i = 0; i &lt;36; i += 3) <br>   &nbsp; &nbsp; &nbsp;  {<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].x = vertices[i + 0].x;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].y = vertices[i + 0].y;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].z = vertices[i + 0].z;<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 1].x = vertices[i + 1].x;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 1].y = vertices[i + 1].y;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 1].z = vertices[i + 1].z;<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 2].x = vertices[i + 2].x;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 2].y = vertices[i + 2].y;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 2].z = vertices[i + 2].z;<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].nx = vertices[i + 0].nx;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].ny = vertices[i + 0].ny;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].nz = vertices[i + 0].nz;<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 1].nx = vertices[i + 1].nx;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 1].ny = vertices[i + 1].ny;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 1].nz = vertices[i + 1].nz;<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 2].nx = vertices[i + 2].nx;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 2].ny = vertices[i + 2].ny;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 2].nz = vertices[i + 2].nz;<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].u = vertices[i + 0].u;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].v = vertices[i + 0].v;<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 1].u = vertices[i + 1].u;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 1].v = vertices[i + 1].v;<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 2].u = vertices[i + 2].u;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 2].v = vertices[i + 2].v;<br>  \u200b<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\/\/ Shortcuts for vertices<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float3 &nbsp;v0 &nbsp;= &nbsp; float3(vertices[i + 0].x,vertices[i + 0].y,vertices[i + 0].z);<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float3 &nbsp;v1 &nbsp;= &nbsp; float3(vertices[i + 1].x,vertices[i + 1].y,vertices[i + 1].z);<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float3 &nbsp;v2 &nbsp;= &nbsp; float3(vertices[i + 2].x,vertices[i + 2].y,vertices[i + 2].z);<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float2 &nbsp;uv0 = &nbsp; float2(vertices[i + 0].u, vertices[i + 0].v);<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float2 &nbsp;uv1 = &nbsp; float2(vertices[i + 1].u, vertices[i + 1].v);<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float2 &nbsp;uv2 = &nbsp; float2(vertices[i + 2].u, vertices[i + 2].v);<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\/\/ Edges of the triangle : postion delta<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float3 &nbsp;deltaPos1 &nbsp; = &nbsp; v1 - v0;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float3 &nbsp;deltaPos2 &nbsp; = &nbsp; v2 - v0;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;\/\/ UV delta<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float2 deltaUV1 &nbsp; &nbsp; = &nbsp; uv1 - uv0;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float2 deltaUV2 &nbsp; &nbsp; = &nbsp; uv2 - uv0;<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float &nbsp; r &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; = &nbsp; 1.0f \/ (deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x);<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float3 tangent &nbsp; &nbsp; &nbsp;= &nbsp; (deltaPos1 * deltaUV2.y - deltaPos2 * deltaUV1.y)*r;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float3 binormal &nbsp; &nbsp; = &nbsp; (deltaPos2 * deltaUV1.x - deltaPos1 * deltaUV2.x)*r;<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].tx = tangent.x; &nbsp;nmVerts[i + 1].tx = tangent.x; &nbsp;nmVerts[i + 2].tx = tangent.x;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].ty = tangent.y; &nbsp;nmVerts[i + 1].ty = tangent.y; &nbsp;nmVerts[i + 2].ty = tangent.y;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].tz = tangent.z; &nbsp;nmVerts[i + 1].tz = tangent.z; &nbsp;nmVerts[i + 2].tz = tangent.z;<br>  \u200b<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].bx = binormal.x; nmVerts[i + 1].bx = binormal.x; nmVerts[i + 2].bx = binormal.x;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].by = binormal.y; nmVerts[i + 1].by = binormal.y; nmVerts[i + 2].by = binormal.y;<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;nmVerts[i + 0].bz = binormal.z; nmVerts[i + 1].bz = binormal.z; nmVerts[i + 2].bz = binormal.z;<br>   &nbsp; &nbsp; &nbsp;  }<br>   &nbsp;  }<\/pre>\n\n\n\n<p><strong>\u9876\u70b9\u7740\u8272\u5668\uff1a<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">   &nbsp; &nbsp; &nbsp; const char* vs &nbsp;= &nbsp; \"#version 330 \\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp;  vec3 &nbsp;  _position;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp;  vec3 &nbsp;  _normal;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp;  vec2 &nbsp;  _uv;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp;  vec3 &nbsp;  _tagent;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp;  vec3 &nbsp;  _biTagent;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;out &nbsp; &nbsp; vec2 &nbsp;  _outUV;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;out &nbsp; &nbsp; vec3 &nbsp;  _outPos;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;out &nbsp; &nbsp; mat3 &nbsp;  _TBN;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uniform mat4 &nbsp;  _mvp;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uniform mat4 &nbsp;  _matWorld;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uniform mat3 &nbsp;  _normalMatrix;; \\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uniform vec3 &nbsp;  _lightPos;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uniform vec3 &nbsp;  _cameraPos;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;void main()\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_outUV &nbsp; &nbsp; &nbsp; &nbsp;  = &nbsp; _uv;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vec4 &nbsp;  pos &nbsp; &nbsp; = &nbsp; _matWorld*vec4(_position,1);\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;mat3 &nbsp;  norMapT = &nbsp; _normalMatrix;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_outPos &nbsp; &nbsp; &nbsp; &nbsp; = &nbsp; pos.xyz;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vec3 &nbsp;  normal &nbsp; &nbsp;  = &nbsp; normalize(norMapT * _normal);\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vec3 &nbsp;  tagent &nbsp; &nbsp;  = &nbsp; normalize(norMapT * _tagent);\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vec3 &nbsp;  biTagent &nbsp;  = &nbsp; normalize(norMapT * _biTagent);\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;_TBN &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;  = &nbsp; mat3x3(tagent,biTagent,normal);\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;gl_Position &nbsp; &nbsp; &nbsp; &nbsp; = &nbsp; _mvp * vec4(_position,1.0);\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}\";<\/pre>\n\n\n\n<p>\u7247\u6bb5\u7740\u8272\u5668\uff1a<\/p>\n\n\n\n<pre class=\"wp-block-preformatted\">   &nbsp; &nbsp;const char* ps = &nbsp; &nbsp;\"#version 330 \\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp;  vec2 &nbsp; &nbsp; &nbsp;  _outUV;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp;  vec3 &nbsp; &nbsp; &nbsp;  _outPos;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;in &nbsp; &nbsp;  mat3 &nbsp; &nbsp; &nbsp;  _TBN;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uniform sampler2D &nbsp; _texture;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uniform sampler2D &nbsp; _texNormal;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uniform vec3 &nbsp; &nbsp; &nbsp;  _lightPos;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;uniform vec3 &nbsp; &nbsp; &nbsp;  _cameraPos;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;void main()\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;gl_FragColor.rgb &nbsp;  = &nbsp; texture2D(_texture, _outUV).rgb;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vec3 &nbsp;  normal &nbsp; &nbsp;  = &nbsp; normalize((_TBN * (texture2D(_texNormal, _outUV).rgb * 2.0 - 1.0)));\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vec3 &nbsp;  lightDir &nbsp;  = &nbsp; normalize(_lightPos - _outPos);\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vec3 &nbsp;  cameraDir &nbsp; = &nbsp; normalize(_cameraPos - _outPos);\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float &nbsp; NdotLD &nbsp; &nbsp;  = &nbsp; max(dot(normal, lightDir), 0.0);\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;gl_FragColor.rgb &nbsp;  *=  0.2 + 0.8 * NdotLD;\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;vec3 &nbsp;  lightDirRef = &nbsp; reflect(-lightDir, normal);\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;float &nbsp; CDdotLDR &nbsp;  = &nbsp; max(dot(cameraDir, lightDirRef), 0.0);\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;gl_FragColor.rgb &nbsp;  +=  pow(CDdotLDR, 64.0);\\n\\<br>   &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}\";<\/pre>\n\n\n\n<p><strong>\u5b8c\u6574\u9879\u76ee\u4ee3\u7801\uff1a<\/strong><\/p>\n\n\n\n<p><a href=\"https:\/\/github.com\/mc-liyanliang\/OpenGL-Shader\/tree\/master\">https:\/\/github.com\/mc-liyanliang\/OpenGL-Shader\/tree\/master<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>\u80cc\u666f \u5728\u4e00\u4e2a\u5e73\u9762\u4e0a\u5982\u679c\u53ea\u6709\u4e00\u4e2a\u6cd5\u7ebf\uff0c\u6574\u4e2a\u9762\u7684\u5149\u7167\u5f3a\u5ea6\u90fd\u662f\u76f8\u540c\u7684\uff0c\u5982\u679c\u662f\u51f9\u51f8\u7684\u8868\u9762\uff0c\u65e0\u6cd5\u8868\u73b0\u8868\u9762\u7684\u771f\u662f\u5149\u7167\u6548\u679c\uff0c\u6240\u4ee5\u5f15\u5165\u4e86\u6cd5\u7ebf\u8d34\u56fe\u3002\u5e73\u9762\u5185\u7684\u6bcf\u4e00\u4e2afragment\u90fd\u5b58\u50a8\u4e00\u4e2a\u6cd5\u7ebf\u5411\u91cf\uff0c\u901a\u8fc7\u6cd5\u7ebf\u5411\u91cf\u8ba1\u7b97\u5207\u7ebf\u5411\u91cf\u548c\u526f\u5207\u5411\u5411\u91cf\u3002 \u5df2\u77e5\u4e0a\u5411\u91cf\u662f\u8868\u9762\u7684\u6cd5\u7ebf\u5411\u91cf\u3002\u53f3\u548c\u524d\u5411\u91cf\u662f\u5207\u7ebf(Tagent)\u548c\u526f\u5207\u7ebf(Bitangent)\u5411\u91cf\u3002\u4e0b\u9762\u7684\u56fe\u7247\u5c55\u793a\u4e86\u4e00\u4e2a\u8868\u9762\u7684\u4e09\u4e2a\u5411\u91cf\uff1a \u8ba1\u7b97\u539f\u7406 \u8ba1\u7b97\u6bcf\u4e2a\u8868\u9762\u7684\u5207\u7ebf\u548c\u526f\u5207\u7ebf\u53ef\u4ee5\u53c2\u7167https:\/\/learnopengl-cn.github.io\/\uff0c\u4e3b\u8981\u8ba1\u7b97\u8fc7\u7a0b\u5982\u4e0b\uff1a \u9876\u70b9\uff1a &nbsp; &nbsp; &nbsp; V3N3UV2 &nbsp;verts[] = &nbsp; &nbsp; &nbsp; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { 0.5f, -0.5f, &nbsp;0.5f , &nbsp;1.0, 0.0, 0.0, 0.0f, 0.0f }, &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; { 0.5f, -0.5f, -0.5f , &nbsp;1.0, 0.0, 0.0, 1.0f, 0&#8230;.<\/p>\n<p class=\"read-more\"><a class=\"btn btn-default\" href=\"http:\/\/liyanliang.net\/index.php\/2022\/02\/03\/normal-mapping\/\"> Read More<span class=\"screen-reader-text\">  Read More<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":470,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[14],"tags":[51],"class_list":["post-469","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-opengl","tag-normalmapping"],"_links":{"self":[{"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/posts\/469","targetHints":{"allow":["GET"]}}],"collection":[{"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/comments?post=469"}],"version-history":[{"count":2,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/posts\/469\/revisions"}],"predecessor-version":[{"id":472,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/posts\/469\/revisions\/472"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/media\/470"}],"wp:attachment":[{"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/media?parent=469"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/categories?post=469"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/liyanliang.net\/index.php\/wp-json\/wp\/v2\/tags?post=469"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}