Opengl着色器问题 – 奇怪的光reflection文物

这几天我一直在摔跤。 我想我已经把它缩小到每个顶点切线的问题了,但我不确定解决这个问题的最好方法。

上下文是iPhone应用程序,opengl es2使用我自己的引擎。 我的着色器是使用提供的每个顶点切线创buildTBNmatrix的凹凸贴图(法线贴图)。 顶点着色器将光vector和眼vector转换为切空间,将它们传递给碎片着色器并计算光照。 但是我的前两个testing模型中的一些几何graphics在光照中显示了奇怪的伪像。 在镜面reflection中最容易看到。

在试图debugging这个我已经取代了正常的地图与平坦的普通PNG ..所有像素是128,128,255。 我也硬编码的颜色。

我的第一个模型是一个button形状。 它显示了神器在外圈上的扇形镜面reflection。 重要的是要注意的是,这里的UV贴图方法是“平坦的”,使得垂直于贴图的边基本上在那里纹理纹理。 我会认为这会使切线难以计算,因为两个点将具有完全相同的纹理坐标。

我尝试debugging渲染设置gl_FragColor不同的variables。 当设置为每个顶点的法线时,我们看到扇形消失,表明法线是正确的。 但是,将其设置为每个顶点的切线时,您可以看到扇贝。

在这里输入图像说明

下一个形状是一个简单的球体。 有了它,模型的顶部和底部就是神器展示的地方。 在线框中,你会看到这是几个三angular形在一个顶点相遇的地方。 因为每个三angular形都有完全不同的紫外线贴图,所以我无法将自己的头围绕在切线上。

如果我不显示着色器代码,我想我会得到很多flack。

顶点着色器:

v_fragmentTexCoord0 = a_vertexTexCoord0; gl_Position = u_modelViewProjectionMatrix * vec4(a_vertexPosition,1.0); vec3 normal = normalize(u_normalMatrix * a_vertexNormal); vec3 tangent = normalize(u_normalMatrix * a_vertexTangent); vec3 bitangent = cross(normal, tangent); mat3 TBNMatrix = mat3(tangent, bitangent, normal); v_eyeVec = -a_vertexPosition.xyz; v_eyeVec *= TBNMatrix; v_lightVec = u_lightPosition - a_vertexPosition.xyz; v_lightVec *= TBNMatrix; v_normal = a_vertexTangent; 

片段着色器:

 vec3 norm = texture2D(u_normalSampler, v_fragmentTexCoord0).rgb * 2.0 - 1.0; vec4 baseColor = vec4(0.6015625,0.0,0.0,1.0); // is normally texture2D(u_textureSampler,v_fragmentTexCoord0); float dist = length(v_lightVec); vec3 lightVector = normalize(v_lightVec); float nxDir = max(0.0, dot(norm, lightVector)); vec4 diffuse = u_lightColorDiffuse * nxDir; float specularPower = 0.0; if(nxDir != 0.0) { vec3 cameraVector = v_eyeVec; vec3 halfVector = normalize(v_lightVec + cameraVector); float nxHalf = max(0.0,dot(norm, halfVector)); specularPower = pow(nxHalf, u_shininess); } vec4 specular = u_lightColorSpecular * specularPower; gl_FragColor = (diffuse * vec4(baseColor.rgb,1.0)) + specular; 

在试图找出着色器,并在网上查看所有的示例和教程,我可以find…我很困惑,为什么凹凸贴图着色器不会干扰3D模型提供的法线贴图。 我猜没有某种参考点你怎么知道如何修改模型的正常? 按什么方向? 我想这就是TBNmatrix的用途。 但在上面的testing中,法线贴图中的法线向量是0,0,1 – 直线上升。 所以它似乎不应该修改它。 任何次数1仍然是1.但是,在math或TBNmatrix中必须有足够的东西,以至于它不会和3d模型中的法线一样。 然后,这个想法与我碰了一下……在我的顶点着色器中,我也首先乘以normalMatrix的顶点法线,以获得它进入模型空间。 但是再一次,那些debugging渲染在被转换之前是顶点正常的。

有没有另一种方法干扰模型的正常,而不使用TBNmatrix? 在没有法线贴图的情况下使用phong着色器进行渲染不会显示工件。

更新:我几乎肯定,问题是由导入应用程序创build的预先准确的切线。 在尝试使用不同的UV地图的不同模型后,我发现类似的问题,有时是黑暗而不是亮点。 所以除非我可以应用没有TBMmatrix的法线贴图或转换到切线空间,否则我需要find另一个导入程序。

更新#2:我刚刚发现这个问题,听起来像是一个线索可能是真正的问题。 三维graphics,单位vector和正交matrix

需要注意的是,这些奇怪的灯光不会发生在顶点,而只发生在它们之间。 即使在球体上,我们也看到了一个顶点和顶点之间的环。 我开始相信这是一个插值问题。 就拿那些三angular形中的一个:

在这里输入图像说明

忽略第二个原因,我正在重新计算这个坏的伤害。 但切线具有相反的极性。 所以在这两个状态之间进行插值的时候,你会得到指向所有地方的向量。

新的问题是我如何解决它? 修正切线? 修复着色器来处理它?

有时最简单的答案是正确的。 切线是不好的。 他们不是正常的正常。

我使用这里描述的方法手动重新计算所有切线和切线:

http://www.terathon.com/code/tangent.html

那个问题就消失了。