为什么为什么我的纹理碎片带有浅色而其他却很暗?

时间:2019-01-09 04:38:25

标签: opengl glsl texture-mapping freeglut bump-mapping

我一直在尝试使用OpenGL实现法线贴图。我已经实现了它的最基本版本,但继续尝试实现 REAL 法线贴图,该法涉及为每个顶点计算Bi-Tangent和Tangets。我首先实现了片段着色器和顶点着色器,如下所示:

顶点着色器:

#version 330 core

in vec4 in_Position;
in vec2 in_Coordinates;
in vec3 in_Normal;
in vec3 tangent;
in vec3 bitangent;

out vec2 ex_textCoord;

out VS_OUT{
    vec3 FragPos;
    vec3 Normal;
    vec4 LightVec;
    vec4 ViewVec;
} vs_out;

uniform mat4 ModelMatrix;
uniform vec4 VertColor;
uniform SharedMatrices
{
    mat4 ViewMatrix;
    mat4 ProjectionMatrix;
};

uniform vec4 plane;

uniform vec3 lightPos;
uniform vec3 viewPos;

void main(void)
{

    vec4 worldPosition = ModelMatrix * in_Position;
    gl_Position = ProjectionMatrix * ViewMatrix * worldPosition;
    vs_out.FragPos = vec3(ModelMatrix * in_Position);
    ex_textCoord = in_Coordinates;

    mat3 normalMatrix = transpose(inverse(mat3(ModelMatrix)));
    vs_out.Normal = normalMatrix * in_Normal;

    vec3 T = normalize(vec3(ModelMatrix * vec4(tangent, 0.0)));
    vec3 N = normalize(vec3(ModelMatrix * vec4(in_Normal, 0.0)));

    T = normalize(T - dot(T, N) * N);

    vec3 B = cross(T, N);

    mat4 TBN4 = mat4(
        vec4(T, 0.0),
        vec4(B, 0.0),
        vec4(N, 0.0),
        worldPosition 
    );

    mat4 invTBN4 = inverse(TBN4);

    vs_out.LightVec = invTBN4 * vec4(normalize(lightPos - worldPosition.xyz), 0.0);
    vs_out.ViewVec  = invTBN4 * vec4(normalize(viewPos - worldPosition.xyz), 0.0);
    //vs_out.TangentFragPos = TBN * vec3(worldPosition);
    gl_ClipDistance[0] = dot(worldPosition, plane);

}

片段着色器:

#version 330 core

out vec4 color;

in vec2 ex_textCoord;

in VS_OUT{
    vec3 FragPos;
    vec3 Normal;
    vec4 LightVec;
    vec4 ViewVec;
} fs_in;

uniform sampler2D screenTexture; //Diffuse Texture
uniform sampler2D normalTexture; //Normal Mapping Texture

uniform bool normalMapping; //Enable or Disable Normal Mapping  

uniform vec3 lightPosition;
uniform vec3 lightColour;

void main()
{
    vec3 normal = texture(normalTexture, ex_textCoord).rgb;
    normal = normalize(normal * 2.0 - 1.0);

    vec3 Normalcolor = texture(screenTexture, ex_textCoord).rgb;

    //Ambient Light
    vec3 ambient = 0.1 * Normalcolor;

    //Diffuse Light
    vec4 lightDir = normalize(fs_in.LightVec);
    float diff = max(dot(vec3(lightDir), normal), 0.0);
    vec3 diffuse = diff * Normalcolor;

    //Specular Light
    vec4 viewDir = normalize(fs_in.ViewVec);
    vec3 reflectDir = reflect(vec3(-lightDir), normal);
    vec4 halfwayDir = normalize(lightDir + viewDir);
    float spec = pow(max(dot(normal, vec3(halfwayDir)), 0.0), 32.0);
    vec3 specular = vec3(0.2) * spec;

    color = vec4(ambient + diffuse + specular, 1.0f);
}

现在诚实地说,着色器对我来说似乎还不错,我一直在看一些示例代码,而我的着色器似乎与它们是1:1的。现在问题出在照明上(我有点怀疑,但是有可能),或者是我计算切线和Bi-Tangent的方式,我在加载网格时会这样做,如下所示:

Vec3 pos1, pos2, pos3, pos4, tangent1, bitangent1, edge1, edge2, normal;
    Vec2 uv1, uv2, uv3, uv4, deltaUV1, deltaUV2;

    for (int i = 0; i <= TempMeshRef->vertexIdx.size() - 3; i += 1) {

        pos1 = TempMeshRef->vertexData[TempMeshRef->vertexIdx[i]-1];
        pos2 = TempMeshRef->vertexData[TempMeshRef->vertexIdx[i+1]-1];
        pos3 = TempMeshRef->vertexData[TempMeshRef->vertexIdx[i+2]-1];
        //pos4 = TempMeshRef->vertexData[TempMeshRef->vertexIdx[i+3]-1];

        uv1 = TempMeshRef->texcoordData[TempMeshRef->texcoordIdx[i]-1];
        uv2 = TempMeshRef->texcoordData[TempMeshRef->texcoordIdx[i+1]-1];
        uv3 = TempMeshRef->texcoordData[TempMeshRef->texcoordIdx[i+2]-1];
        //uv4 = TempMeshRef->texcoordData[TempMeshRef->texcoordIdx[i+3]-1];

        normal = TempMeshRef->normalData[TempMeshRef->normalIdx[i]-1];

        //Triangle 1

        edge1 = pos2 - pos1;
        edge2 = pos3 - pos1;
        deltaUV1 = uv2 - uv1;
        deltaUV2 = uv3 - uv1;

        GLfloat f = 1.0f / (deltaUV1.x * deltaUV2.y - deltaUV2.x * deltaUV1.y);

        tangent1.x = f * (deltaUV2.y * edge1.x - deltaUV1.y * edge2.x);
        tangent1.y = f * (deltaUV2.y * edge1.y - deltaUV1.y * edge2.y);
        tangent1.z = f * (deltaUV2.y * edge1.z - deltaUV1.y * edge2.z);
        tangent1 = Normalized(tangent1);

        TempMeshRef->tangentData.push_back(tangent1);

        bitangent1.x = f * (-deltaUV2.x * edge1.x + deltaUV1.x * edge2.x);
        bitangent1.y = f * (-deltaUV2.x * edge1.y + deltaUV1.x * edge2.y);
        bitangent1.z = f * (-deltaUV2.x * edge1.z + deltaUV1.x * edge2.z);
        bitangent1 = Normalized(bitangent1);

        TempMeshRef->biTangentData.push_back(bitangent1);

现在,为了让您观察我得到的结果,它们是以下错误:

Bug

之所以认为这与灯光无关,是因为根据我计算切线和切线的方式,或多或少的片段被“启发”了

0 个答案:

没有答案