2017-01-02 198 views
3

我目前正在研究我的第一个基于OpenGL的游戏引擎。我需要法线贴图作为功能,但它不能正常工作。OpenGL法线贴图问题 - 法线可能面对错误的方向?

Here is an animation of what is Happening

的工件被光并在表面上的法线之间的角度的影响。相机移动不会以任何方式影响它。我也是(现在至少在现在)采用效率较低的方法,将从法线贴图提取的法线转换为视图空间,而不是将所有东西都转换为切线空间。

这里是我的代码的相关部分:

生成切线和Bitangents

 for(int k=0;k<(int)mb->getIndexCount();k+=3) 
     { 
      unsigned int i1 = mb->getIndex(k); 
      unsigned int i2 = mb->getIndex(k+1); 
      unsigned int i3 = mb->getIndex(k+2); 

      JGE_v3f v0 = mb->getVertexPosition(i1); 
      JGE_v3f v1 = mb->getVertexPosition(i2); 
      JGE_v3f v2 = mb->getVertexPosition(i3); 

      JGE_v2f uv0 = mb->getVertexUV(i1); 
      JGE_v2f uv1 = mb->getVertexUV(i2); 
      JGE_v2f uv2 = mb->getVertexUV(i3); 

      JGE_v3f deltaPos1 = v1-v0; 
      JGE_v3f deltaPos2 = v2-v0; 
      JGE_v2f deltaUV1 = uv1-uv0; 
      JGE_v2f deltaUV2 = uv2-uv0; 

      float ur = deltaUV1.x * deltaUV2.y - deltaUV1.y * deltaUV2.x; 

      if(ur != 0) 
      { 
       float r = 1.0/ur; 

       JGE_v3f tangent; 
       JGE_v3f bitangent; 

       tangent = ((deltaPos1 * deltaUV2.y) - (deltaPos2 * deltaUV1.y)) * r; 
       tangent.normalize(); 

       bitangent = ((deltaPos1 * -deltaUV2.x) + (deltaPos2 * deltaUV1.x)) * r; 
       bitangent.normalize(); 

       tans[i1] += tangent; 
       tans[i2] += tangent; 
       tans[i3] += tangent; 
       btans[i1] += bitangent; 
       btans[i2] += bitangent; 
       btans[i3] += bitangent; 
      } 
     } 

Here's a picture of the Tangents

计算在顶点着色器 的TBN矩阵(mNormal校正为正常的非统一标尺)

vec3 T = normalize((mVW * vec4(tangent, 0.0)).xyz); 
tnormal = normalize((mNormal * n).xyz); 
vec3 B = normalize((mVW * vec4(bitangent, 0.0)).xyz); 

tmTBN = transpose(mat3(
T.x, B.x, tnormal.x, 
T.y, B.y, tnormal.y, 
T.z, B.z, tnormal.z)); 

最后这里是我用的采样从一般的法线贴图,并试图将其转换成片段着色器来查看空间

fnormal = normalize(nmapcolor.xyz * 2.0 - 1.0); 
fnormal = normalize(tmTBN * fnormal); 

“nmapcolor”是从正常的地图样本颜色。 然后在照明计算中使用“正常”。

我一直在试图解决这个问题这么久,绝对不知道如何让这个工作。任何帮助将不胜感激。

编辑 - 我稍微修改了代码以在世界空间中工作并输出结果。大平台没有正常的映射(并且它工作正常),而较小的平台却没有。 World Space Normals

我在法线目前的方向增加。它们应该通常是相同的颜色,但它们明显不同。似乎mTBN矩阵并未正确地将切线空间正常转换为世界(和通常查看)空间。

+0

这可能是一个愚蠢的问题,但是你是否应该在顶点着色器中通过'mVW'来转换'tnormal'? – Jadh4v

+0

尝试这并不解决它。我认为'mNormal'处理这个问题,因为它是mVW的逆转置。 – Ruxify

+0

尝试反转'nmapcolor.y = 1 - nmapcolor.y',也许你在某处y轴是向上或向下约定混合的。 – ybungalobill

回答

0

嗯......我解决了这个问题。原来我的正常映射实现是完美的。这个问题实际上是在我的纹理类中。这当然是我第一次编写OpenGL渲染引擎,并且我没有意识到我的纹理类中的unlock()函数将所有纹理保存为GL_SRGB_ALPHA,包括法线贴图。只有漫反射贴图纹理应该是GL_SRGB_ALPHA。暂时强制所有纹理加载,因为GL_RGBA解决了这个问题。 不能相信我有这个问题11个月,只是发现它是如此之小。