2013-03-10 46 views
4

我是按照正常映射许多在线教程,并且已经得到了它的工作,在一定程度上......我似乎法线贴图问题

不能让它正常工作,除非多边形是垂直于视图矢量。

我已经创建了一个视频来说明这一点,因为图片并不足以展示我的意思。

http://www.youtube.com/watch?v=9D4o_zy-61s

我已经发布我的着色器:

顶点:

#version 400 
layout (location = 0) in vec3 attribPosition; 
layout (location = 1) in vec3 attribNormal; 
layout (location = 2) in vec2 attribTexCoord; 
layout (location = 3) in vec3 attribTangent; 
layout (location = 3) in vec3 attribBinormal; 

uniform mat4 mvp; 
uniform mat4 mvm; 
uniform mat3 nm; 
uniform vec3 lightPos_World; 

out vec2 vUvs; 
out vec3 lightPos_Eye; 
out vec3 vertexPos_Eye; 
out vec3 normalDir_Eye; 
out vec3 normalDir_World; 
out mat3 tbnMatrix; 

void main() 
{ 
    vUvs = attribTexCoord; 
    normalDir_World = attribNormal; 
    normalDir_Eye = (nm * attribNormal); 
    vec3 t = nm * attribTangent; 
    vec3 n = nm * attribNormal; 
    vec3 b = nm * cross(n,t); 

    mat3 tbnMatrix = mat3(t.x, b.x, n.x, 
          t.y, b.y, n.y, 
          t.z, b.z, n.z); 

    vertexPos_Eye = (mvm * vec4(attribPosition,1.0)).xyz; 
    lightPos_Eye = (mvm * vec4(lightPos_World,1.0)).xyz; 

    gl_Position = mvp * vec4(attribPosition,1.0); 
} 

片段:

#version 400 
layout(location = 0) out vec4 frag_main; 
struct PointLight{ 
    vec3 position; 
    vec3 ambient; 
    vec3 diffuse; 
    vec3 specular; 
    float shininess; 
    float intensity; 
}; 

uniform PointLight light[2]; 
uniform sampler2D colorTexture; 
uniform sampler2D normalTexture; 
uniform mat4 mvm; 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
// FLAGS - all flags start false; 
// [0][0] = colour map 
// [0][1] = normal map 
// [0][2] = unused 
// [0][3] = show normal map in colour channel 
// [1][0] = use tangent space 
// [1][1] = unused 
// [1][2] = unused 
// [1][3] = unused 
// ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 
uniform bvec4 flags[2]; 

in vec3 vertexPos_Eye; 
in vec3 normalDir_World; 
in vec3 normalDir_Eye; 
in vec2 vUvs; 
in mat3 tbnMatrix; 


void main(){ 

    uint numLights=2; 

    vec3 colorFragment; 
    if(flags[0][0]){ 
     colorFragment = texture(colorTexture,vUvs).xyz; 
    }else{ 
     colorFragment = vec3(0.5); 
    } 

    vec3 normalMapNormal = (texture(normalTexture,vUvs).rgb * 2) - 1; 
    vec3 normalDir; 
    if(flags[0][1]){ 
     normalDir = normalize(normalDir_Eye); 
    }else{ 
     normalDir = normalize(normalMapNormal.rgb); 
    } 

    vec4 outColor = vec4(1); 
    outColor.xyz = vec3(0); 

    float duller = 1/numLights; 
    for(int i = 0;i< numLights;i++){ 
     vec3 lightPos_Eye = (mvm * vec4(light[i].position,1.0)).xyz; 
     vec3 lightDir_Eye = normalize(lightPos_Eye - vertexPos_Eye); 
     vec3 lightDir_Tangent = lightDir_Eye * tbnMatrix; 

     vec3 vertDir_Eye = normalize(-vertexPos_Eye); 
     vec3 vertDir_Tangent = vertDir_Eye * tbnMatrix; 

     vec3 halfDir_Eye = normalize(vertDir_Eye + lightDir_Eye); 
     vec3 halfDir_Tangent = halfDir_Eye * tbnMatrix; 

     vec3 Ia = colorFragment.xyz * light[i].ambient; 
     vec3 Id; 
     vec3 Is; 

     // tangent space 
     Id = (colorFragment.xyz * light[i].diffuse) * max(dot(lightDir_Tangent, normalDir), 0); 
     Is = light[i].specular * pow(max(dot(halfDir_Eye, normalDir), 0), light[i].shininess*2); 
     // eye space 
     //Id = (colorFragment.xyz * light[i].diffuse) * max(dot(lightDir_Eye, normalDir), 0); 
     //Is = light[i].specular * pow(max(dot(halfDir_Eye, normalDir), 0), light[i].shininess*2); 

     outColor.xyz += (Ia + Id + Is); 

    } 

    if(flags[0][3]){ 
     outColor.xyz = normalDir; 
    } 
    frag_main = (outColor); 
} 
+0

对于视频演示+1。 – 2013-03-10 08:03:26

回答

0

我注意到行:

vec3 b = nm * cross(n,t); 

,但它应该是:

vec3 b = cross(n,t); 

没有必要通过nm再次倍增,因为nt在所需的摄像机空间。

另一件事:

lightPos_Eye = (mvm * vec4(lightPos_World,1.0)).xyz; 

由于lightPos_World是世界空间(如名字所暗示的),你应该像* world_matrix *通过模型视图相乘,不是。或者只需在应用程序代码中计算lightPos_Eye并将其发送到顶点着色器。

很难管理所有这些不同的载体,并将它们放在一个合适的空间中。有时候,视觉错误是非常微妙的,很难发现。

+0

感谢您的快速响应!不幸的是,在我做出这样的改变后它仍然是一样的。 – finlaybob 2013-03-10 11:59:43

+0

我添加了一件我注意到的事情 - 可能是错误的光线位置计算。希望它有帮助 – fen 2013-03-10 14:10:25

+0

我也试着改变这一点。随着这种改变,灯光相对于相机保持不变,并且将其乘以模型视图矩阵(我只从相机旋转中获取)是一种修复,以使灯光相对于相机移动保持“静止”。 它不能解决需要垂直于多边形的问题,但不幸的是。 虽然我没有想过尝试,所以谢谢! – finlaybob 2013-03-10 14:46:05