正常映射和使用不正确的镜面分量的phong着色 [英] Normal mapping and phong shading with incorrect specular component

查看:178
本文介绍了正常映射和使用不正确的镜面分量的phong着色的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在世界空间坐标(我发现那些更容易使用)和我的照明工作正常没有正常映射正常/凹凸映射,但当引入正常映射(和使用TBN矩阵计算的新向量)

I'm implementing normal/bump mapping in world space coordinates (I find those easier to work with) and my lighting worked fine without normal mapping, but when introducing normal mapping (and the new vectors calculated with the TBN matrix) the specular component of my lighting is off.

镜面反射分量不在摄像机和光源之间,因此应该是这样的。然而,看看我的代码,我找不到任何问题。切线和bitangent来自ASSIMP对象加载器,eyePos和lightPos也在世界坐标中。

The specular component is not between the camera and the light where it should be so something is wrong. However, looking at my code I could not find any issues. The tangent and bitangent come from the ASSIMP object loader and the eyePos and lightPos are in world coordinates as well.

由于照明似乎在镜面部分看起来是正确的(使用凹凸贴图显示),我认为它与切线空间变换有关系。

Since the lighting seems to look correct at the specular section (with the bump mapping shown) I assume it has something to do with the tangent space transformation?

以下是显示问题的图片:

Here is a picture demonstrating the issue:

顶点着色器:

#version 330
layout (location = 0) in vec4 vertex;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec3 tangent;
layout(location = 3) in vec3 bitangent;
layout(location = 5) in vec2 texCoord;

uniform mat4 projection;
uniform mat4 view;
uniform mat4 model;
uniform vec3 lightPos; 
uniform vec3 eyePos;

out vec3 Position;
out vec2 TexCoord;

out vec3 tangentLightDir;
out vec3 tangentViewDir;

void main()
{
    gl_Position = projection * view * model * vertex;
    // Position
    Position = vec3(model * vertex);
    // Normal
    mat3 normalMat = transpose(inverse(mat3(model)));
    Normal = normalize(normalMat * normal);
    // Texture
    TexCoord = texCoord;

    // Normal mapping
    mat3 TBN = mat3(tangent, bitangent, Normal);
    TBN = transpose(TBN);
    // Get direction vectors:
    vec3 lightDir = normalize(lightPos - Position);
    vec3 viewDir = normalize(eyePos - Position); 
    // Now transform them to tangent space
    tangentLightDir = TBN * lightDir;
    tangentViewDir = TBN * viewDir;
}

片段着色器:

#version 330
in vec3 Position;
in vec2 TexCoord;

in vec3 tangentLightDir;
in vec3 tangentViewDir;

uniform sampler2D texture0;
uniform sampler2D texture_normal;

out vec4 outColor;

void main()
{
    // defaults
    vec4 ambient = vec4(0.1);
    vec4 diffuse = vec4(0.4);
    vec4 specular = vec4(0.5);
    vec4 texColor = texture(texture0, TexCoord);    

    // Phong shading
    vec3 LightDir = normalize(tangentLightDir);
    vec3 Norm = normalize(texture(texture_normal, TexCoord).xyz * 2.0 - 1.0);    

    vec3 ViewDir = normalize(tangentViewDir); 
    vec3 ReflectDir = reflect(-LightDir,Norm);
    float specularContribution = pow(max(dot(ViewDir, ReflectDir), 0.0), 32);
    // Calculate diffuse component
    vec4 I = diffuse * max(dot(LightDir, Norm), 0.0);
    diffuse = clamp(I, 0.0, 1.0);
    // Calculate specular component
    specular = specular * specularContribution;

    outColor = texColor * (diffuse + specular + ambient);
}


推荐答案

layout(location = 3) in vec3 bitangent;
layout(location = 5) in vec2 texCoord;

5 是正确的位置吗?

关于TBN矩阵。您必须( jhoffman0x )将 normalMat 矩阵乘以 tangent bitangent ,将结果标准化,之后进行 TBN 矩阵:

About TBN matrix. You must (how say jhoffman0x) multiply normalMat matrix to tangent and bitangent, normalize result and after make TBN matrix:

a href =https://github.com/daw42/glslcookbook =nofollowtitle =w> David Wolff - OpenGL 4.0 Shading Language Cookbook 。顶点着色器:

Example from David Wolff - OpenGL 4.0 Shading Language Cookbook. Vertex Shader:

#version 430

layout (location = 0) in vec3 VertexPosition;
layout (location = 1) in vec3 VertexNormal;
layout (location = 2) in vec2 VertexTexCoord;
layout (location = 3) in vec4 VertexTangent;

struct LightInfo {
  vec4 Position;  // Light position in eye coords.
  vec3 Intensity; // A,D,S intensity
};
uniform LightInfo Light;

out vec3 LightDir;
out vec2 TexCoord;
out vec3 ViewDir;

uniform mat4 ModelViewMatrix;
uniform mat3 NormalMatrix;
uniform mat4 ProjectionMatrix;
uniform mat4 MVP;

void main()
{
    // Transform normal and tangent to eye space
    vec3 norm = normalize( NormalMatrix * VertexNormal );
    vec3 tang = normalize( NormalMatrix * vec3(VertexTangent) );
    // Compute the binormal
    vec3 binormal = normalize( cross( norm, tang ) ) * VertexTangent.w;

    // Matrix for transformation to tangent space
    mat3 toObjectLocal = mat3(
        tang.x, binormal.x, norm.x,
        tang.y, binormal.y, norm.y,
        tang.z, binormal.z, norm.z ) ;

    // Transform light direction and view direction to tangent space
    vec3 pos = vec3( ModelViewMatrix * vec4(VertexPosition,1.0) );
    LightDir = normalize( toObjectLocal * (Light.Position.xyz - pos) );

    ViewDir = toObjectLocal * normalize(-pos);

    TexCoord = VertexTexCoord;

    gl_Position = MVP * vec4(VertexPosition,1.0);
}

碎片着色器:

#version 430

in vec3 LightDir;
in vec2 TexCoord;
in vec3 ViewDir;

layout(binding=0) uniform sampler2D ColorTex;
layout(binding=1) uniform sampler2D NormalMapTex;

struct LightInfo {
  vec4 Position;  // Light position in eye coords.
  vec3 Intensity; // A,D,S intensity
};
uniform LightInfo Light;

struct MaterialInfo {
  vec3 Ka;            // Ambient reflectivity
  vec3 Ks;            // Specular reflectivity
  float Shininess;    // Specular shininess factor
};
uniform MaterialInfo Material;

layout( location = 0 ) out vec4 FragColor;

vec3 phongModel( vec3 norm, vec3 diffR ) {
    vec3 r = reflect( -LightDir, norm );
    vec3 ambient = Light.Intensity * Material.Ka;
    float sDotN = max( dot(LightDir, norm), 0.0 );
    vec3 diffuse = Light.Intensity * diffR * sDotN;

    vec3 spec = vec3(0.0);
    if( sDotN > 0.0 )
        spec = Light.Intensity * Material.Ks *
               pow( max( dot(r,ViewDir), 0.0 ), Material.Shininess );

    return ambient + diffuse + spec;
}

void main() {
    // Lookup the normal from the normal map
    vec4 normal = 2.0 * texture( NormalMapTex, TexCoord ) - 1.0;

    vec4 texColor = texture( ColorTex, TexCoord );
    FragColor = vec4( phongModel(normal.xyz, texColor.rgb), 1.0 );
}

这篇关于正常映射和使用不正确的镜面分量的phong着色的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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