0
votes

I am working on a shader where the fragment shader should work in the tangent space. It works just as expected for both the ambient and diffuse light, but the specular light is just plain weird. It seems that nearby fragments can have a lot or no light with no obvious reasons. Frame rendered by OpenGL

The vertex shader is:

#version 330 core
layout (location = 0) in vec3 inVertex;
layout (location = 1) in vec3 inNormal;
layout (location = 2) in vec2 inTexture;
layout (location = 3) in vec3 inTangent;
layout (location = 4) in vec3 inBitangent;

out vec3 FragmentPosition;
out vec2 TextureCoordinate;
out vec3 TangentLightDirection;
out vec3 TangentViewPosition;
out vec3 TangentFragmentPosition;


void main()
{
    FragmentPosition = vec3(inVertex);
    vec3 normal = normalize(inNormal);
    gl_Position = vec4( inVertex, 1 );
    TextureCoordinate = inTexture;

    vec3 tangent = normalize(inTangent);
    vec3 biTangent = normalize(inBitangent);

    mat3 toTangentSpaceTransformation = transpose(mat3(tangent,biTangent,normal));
    TangentFragmentPosition = toTangentSpaceTransformation * FragmentPosition;
    TangentLightPosition = toTangentSpaceTransformation * vec3(0,1,1);
    TangentFragmentPosition = toTangentSpaceTransformation * vec3(0,0,3);
}

And the fragment shader is:

#version 330 core
out vec4 FragColor;

in vec3 FragmentPosition;
in vec2 TextureCoordinate;
in vec3 TangentLightDirection;
in vec3 TangentViewPosition;
in vec3 TangentFragmentPosition;

uniform sampler2D Texture;
uniform sampler2D normalTexture;


void main() {
    vec3 normal = vec3(0,0,1);

    float shininess = 4;
    vec3 phongVector = vec3(0.3,0.7,1);
    vec4 color = texture(Texture,TextureCoordinate);
    vec4 ambientLightColor = vec4(1,1,1,1);//vec4(normalOffset,1);

    // Calculation of ambient light
    vec4 sunLightColor = vec4(1,1,1,1);
    vec3 sunLightDirection = normalize(TangentLightPosition);
    vec4 ambientLight = phongVector[0] * ambientLightColor;

    // Calculation of diffuse light
    float diffuseConst = max(dot(normal,sunLightDirection),0.0);
    vec4 diffuseLight = phongVector[1] * diffuseConst * sunLightColor;

    // Calculation of specular light
    vec3 viewDirection = normalize(TangentViewPosition - TangentFragmentPosition);
    vec3 reflectionDirection = reflect(-sunLightDirection,normal);
    float spec = pow(max(dot(reflectionDirection,viewDirection),0),shininess);
    vec4 specularLight = phongVector[2] * spec * sunLightColor;

    FragColor = (specularLight)*color;
}
1
You shouldn't be passing tangent and bitangent values in as vertex attributes. Send in position, normal, and texture values to your vertex shader, and a single uniform camera position into your fragment shader, then calculate the reflection and everything else in the fragment. That way there aren't any artifacts from interpolation. - Ty Staszak
These are not interpolation artifacts... this looks like using uninitialized variables. A good way to debug this is to one-by-one render out each individual term used in the failing equation to check if the values look how you'd expect them to. It might very well be that you didn't correctly setup the attribute pointers for the tangent and bitangents. - LJᛃ

1 Answers

0
votes

It was a typo. tangentFragmentPosition was initialized twice, while tangentViewPosition was not initialized at all. Initizalizing tangentViewPosition gave the desired result.