【问题标题】:GLSL normal mapping issueGLSL法线贴图问题
【发布时间】:2013-07-16 18:44:27
【问题描述】:

下面列出了法线贴图的着色器代码。尽管如此,由于生成的图像不正确,因此代码有问题。正常情况似乎已关闭。其他功能似乎工作正常,所以我相信问题出在着色器上。有什么想法可能是错的吗?

顶点着色器

#version 150

in vec3 position;
in vec2 texcoord;
in vec3 normal;
in vec3 tangent;
in vec3 bitangent;

out vec2 Texcoord;
out vec3 VertexPos_World;
out vec3 LightDir_Tan;

uniform vec3 lightPos0_World;
uniform mat4 model;
uniform mat4 view;
uniform mat4 proj;

void main() 
{
    gl_Position = proj * view * model * vec4(position, 1.0);
    Texcoord = texcoord;    
    VertexPos_World = (model * vec4(position, 1.0)).xyz;

    vec3 normal_Cam = (view * model * vec4(normal, 1.0)).xyz;
    vec3 tangent_Cam = (view * model * vec4(tangent, 1.0)).xyz;
    vec3 bitangent_Cam = (view * model * vec4(bitangent, 1.0)).xyz; 

    mat3 TBN = transpose(mat3(tangent_Cam, bitangent_Cam, normal_Cam));

    vec3 lightDir_Cam = lightPos_Cam - vertexPos_Cam;
    LightDir_Tan = TBN * lightDir_Cam;
}

片段着色器

#version 150

in vec2 Texcoord;
in vec3 VertexPos_World;
in vec3 LightDir_Tan;

out vec4 outColor;

uniform vec3 lightPos0_World;
uniform vec3 lightColor0;
uniform float lightPower0;

uniform vec3 ambientColor;
uniform vec3 diffuseColor;
uniform sampler2D tex0;
uniform sampler2D tex0normal;

void main() 
{
    float lightDistance = length(lightPos0_World - VertexPos_World);

    vec3 materialDiffuseColor = texture(tex0, Texcoord).xyz * diffuseColor;
    vec3 materialAmbientColor = ambientColor * materialDiffuseColor;

    vec3 n = normalize(texture(tex0normal, Texcoord).rgb * 2.0 - 1.0);
    vec3 l = normalize(LightDir_Tan);
    float diff = clamp(dot(n,l), 0, 1);

    outColor.rgb = 
            materialAmbientColor +
            materialDiffuseColor * lightColor0 * lightPower0 * diff / (lightDistance * lightDistance);
}

【问题讨论】:

  • 你能发布你发送到 GPU 的内容吗?

标签: c++ opengl glsl


【解决方案1】:

这可能不是唯一的问题,但在你的着色器中你有:

vec3 normal_Cam = (view * model * vec4(normal, 1.0)).xyz;
vec3 tangent_Cam = (view * model * vec4(tangent, 1.0)).xyz;
vec3 bitangent_Cam = (view * model * vec4(bitangent, 1.0)).xyz; 

这应该是:

vec3 normal_Cam = (view * model * vec4(normal, 0.0)).xyz;
vec3 tangent_Cam = (view * model * vec4(tangent, 0.0)).xyz;
vec3 bitangent_Cam = (view * model * vec4(bitangent, 0.0)).xyz; 

使用0.0 而不是1.0,因为这些是方向向量,而不是位置,所以您想忽略矩阵中的平移。

此外,您应该在您的应用程序中将这些矩阵相乘,并在着色器中使用统一的 view_model(否则您将按顶点而不是按模型进行这项工作)。

【讨论】:

    【解决方案2】:

    您的法线很可能非常偏离。确保提交一个每个面有 4 个顶点的立方体,而不是提交一个具有 8 个顶点的立方体,以便您可以为每个面发送正确的法线。否则,插值器将仅使用索引相邻三角形的法线,这就是导致该问题的原因。

    【讨论】:

    • 为了调试法线,请尝试设置outColor.rgb = n-n。与使用完整的 Phong 着色器相比,查看正在发生的事情要容易得多。
    猜你喜欢
    • 2012-01-12
    • 1970-01-01
    • 2013-08-14
    • 2014-04-30
    • 1970-01-01
    • 2012-04-22
    • 1970-01-01
    • 2013-05-08
    • 1970-01-01
    相关资源
    最近更新 更多