OpenGL着色问题 - 奇怪的光反射文物 [英] Opengl shader problems - weird light reflection artifacts

查看:250
本文介绍了OpenGL着色问题 - 奇怪的光反射文物的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在摔跤这个好几天。我想,我终于把范围缩小到与每个顶点切线问题,但我不知道最好的方式来解决这个问题。

I've been wrestling with this for days. I think I've finally narrowed it down to a problem with the per vertex tangents, but I'm not sure the best way to fix it.

上下文是iPhone应用程序,用我自己的发动机的OpenGL ES2。我的着色器是使用附带的每个顶点的切线营造TBN矩阵凹凸贴图(法线贴图)品种。顶点着色器转换的光载体和眼向量正切空间,并将它们传递到片段着色器和计算所述灯。但在我的前两个测试模型的一些几何形状呈现不可思议文物照明。这是最容易看到的镜面组成部分。

Context is iPhone app, opengl es2 using my own engine. My shader is a bump map (normal map) variety using the supplied per vertex tangent to create a TBN matrix. The vertex shader transforms the light vectors and eye vectors to tangent space, passes them to the fragment shader and calculates the lights. But some geometry in my first two test models is showing weird artifacts in the lighting. It is easiest to see in the specular component.

在试图调试这一点,我把它换成了一台正常的PNG法线贴图......所有像素128128255。我也很难codeD的颜色。

In trying to debug this I've replaced the normal map with a flat normal png.. all pixels are 128,128,255. I also hard coded the color.

我的第一个模型是一个按钮的形状。它显示了神器的扇形镜面打在外环上。重要的是要注意的是,这里的UV映射方法是平面,以使它们垂直于所述映射基本上条纹横跨有纹理的两侧。我认为这会使得很难切线来计算的几何形状,因为两个点的将有相同的纹理坐标。

My first model is a button shape. It shows the artifact as a scalloped specular hit on the outside ring. Important to note is that the UV mapping method here was 'flat' to make the sides which are perpendicular to the mapping basically streak the texture across there. I would think this would make the tangents hard to calculate for that geometry since two of the points would have the exact same texture coordinate.

我试着调试渲染设置gl_FragColor不同的变量。当它设置为每个顶点的法线,我们看到了扇形消失了,这表明法线是正确的。但是,将其设置为每个顶点切线时,你可以看到扇贝。

I tried debug renders setting gl_FragColor to different variables. When setting it to the per vertex normals we see the scalloping is gone, indicating that the normals are correct. But when setting it to the per vertex tangents you can see the scallop.

接下来的形状是一个简单的球。有了它最顶端的模式和底部就是神器节目。在线框,你会看到,这是在几个三角形正在开一个顶点。我不能完成我的头周围是什么意思的切线,因为每个三角形有完全不同的UV贴图那里。

The next shape is a simple sphere. With it the very top and bottom of the model is where the artifact shows. In the wireframe you'll see that this is where several triangles are meeting at one vertex. I can't wrap my head around what that means for the tangents as each triangle has completely different UV mapping there.

我想我会得到很多宣传,如果我不显示着色器code ...

I suppose I'll get a lot of flack if I don't show the shader code...

顶点着色器:

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;

片段着色器:

Fragment Shader:

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;

在试图找出着色器,看着所有的样本和教程在网上我可以找到...我很困惑于为什么凹凸贴图着色器将不只是扰乱了3D模型所提供的法线贴图。我想没有某种形式的参考点,你怎么知道如何修改模型的正常吗?通过什么样的方向?我想这就是TBN矩阵是什么。但在我的测试上面法线贴图法向量是0,0,1 - 直线上升。因此,现在看来似乎不应该改变它。任何时间1还是1。但是,必须有一些在数学或TBN矩阵,它不是未来与正常人一样的人在三维模型搞砸了就好了。然后这个想法击中一些与我..在我的顶点着色器,我也是第一次乘顶点正常的normalMatrix得到它到模型空间。但话又说回来,这些调试渲染是顶点正常,它被改造了。

In trying to figure out the shader and looking at all the samples and tutorials online I could find... I was confused by why the bump map shaders wouldn't just perturb the normal map supplied by the 3d model. I guess without some sort of reference point how you know HOW to modify model's normal? By what orientation? I guess that's what the TBN matrix is for. But in my test above the normal vector in the normal map is 0,0,1 - straight up. So it seems like it shouldn't be modifying it at all. Anything times 1 is still 1. But there must be something screwed up enough in the math or in the TBN matrix that it's not coming up with the same normal as the one in the 3d model. Then that idea struck something with me.. that in my vertex shader I'm also first multiplying the vertex normal by the normalMatrix to get it in to model space. But then again, those debug renders are of the vertex normal before it was transformed.

是否有其他方法扰乱模型的正常不使用TBN矩阵?有蓬着色渲染不正常的地图不显示的神器。

Is there another method to perturb the model's normal without using a TBN matrix? Rendering with a phong shader without the normal map doesn't show the artifact.

更新:我几乎可以肯定,这个问题是由进口的应用程序创建的precalulated切线。在尝试不同的型号,不同的紫外线地图我发现类似的问题看,有时它是一个黑暗的,而不是一大亮点。所以,除非我可以申请一个正常的地图没有TBM矩阵或转换到切线空间,我需要找到另一位进口商。

UPDATE: I'm almost positive that the problem is the precalulated tangents created by the importing app. After trying different models with different UV Maps I'm finding similar looking problems, sometimes it's a darkness instead of a highlight. So unless I can apply a normal map without a TBM matrix or converting to tangent space, I will need to find another importer.

更新#2:我刚刚发现,听起来像它可能是一个线索,真正的问题本的其他问题。 <一href="http://stackoverflow.com/questions/4553503/3d-graphics-unit-vectors-and-orthogonal-matrices">3d显卡,单位向量和正交矩阵

UPDATE #2: I just found this other question that sounds like it might be a clue to the real problem. 3d graphics, unit vectors and orthogonal matrices

重要的是要注意,这些怪异的灯不发生在顶点,但只有在他们之间。甚至在球体我们看到一个环,该环是顶部顶点和那些权利下方之间。我开始相信,这是一个插值问题。把这些三角形的只是一个在那里:

It's important to note that these weird lights don't happen on vertices but only in between them. Even on the sphere we're seeing a ring which is between the top vertex and the ones right below it. I'm starting to believe that this is an interpolation problem. Take just one of those triangles up there:

忽略坏的二重的第二个原因,我重新计算了。但切线具有相反的极性。因此,尽管这两个状态之间进行插值处理您将得到的那点所有的地方载体。

Ignore the bad bitangent for a second cause I'm recalculating that. But the tangents have opposite polarity. So while being interpolated between those two states your going to get vectors that point all over the place.

新的问题是如何解决这个问题呢?固定切线?固定着色器处理呢?

The new question is how do I solve it? Fixing the tangents? Fixing the shader to deal with it?

推荐答案

有时候,最简单的答案是正确的。该切线是坏的。他们不是垂直于正常

Sometimes the simplest answer is the right one. The tangents were bad. They were not orthogonal to the normal.

我手动重新计算所有的切线,并使用此处描述的方法bitangents:

I manually recalculated all the tangents and bitangents using the methods described here:

http://www.terathon.com/$c$c/tangent。 HTML

和这个问题就走了。

这篇关于OpenGL着色问题 - 奇怪的光反射文物的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆