5

I have a simple Vulkan setup that loads a quite large mesh file (woman) and also applies the diffuse and normal map textures.

Vertex Shader:

#version 450 core

layout (set = 0, binding = 0) uniform ModelMatrix {
    mat4 model;
} modelMatrix;

layout (push_constant) uniform ViewProjection {
    mat4 view;
    mat4 projection;
} viewProjection;

layout (location = 0) in vec3 inPos;

layout (location = 1) in vec3 inNor;

layout (location = 2) in vec2 inUV;

layout (location = 3) in vec3 inTan;

layout (location = 4) in vec3 inBitan;

layout (location = 0) out vec3 fragPos;

layout (location = 1) out vec2 fragUV;

layout (location = 2) out vec3 fragNor;

layout (location = 3) out vec3 fragTan;

layout (location = 4) out vec3 fragBitan;


void main()
{
    fragPos     = vec3(viewProjection.view * modelMatrix.model * vec4(inPos, 1.0));
    fragNor     = mat3(viewProjection.view * modelMatrix.model) * inNor;
    fragUV      = inUV;
    fragTan     = mat3(viewProjection.view * modelMatrix.model) * inTan;
    fragBitan   = mat3(viewProjection.view * modelMatrix.model) * inBitan;


    gl_Position = viewProjection.projection * vec4(fragPos, 1.0);
}

Fragment Shader:

#version 450 core

layout (location = 0) in vec3 fragPos;

layout (location = 1) in vec2 fragUV;

layout (location = 2) in vec3 fragNor;

layout (location = 3) in vec3 fragTan;

layout (location = 4) in vec3 fragBitan;

layout (location = 0) out vec4 outFragColor;

layout (set = 0, binding = 0) uniform MVP {
    mat4 model;
} mvp;

layout (set = 0, binding = 1) uniform sampler2D textureSampler;

layout (set = 0, binding = 2) uniform sampler2D normalSampler;

layout (set = 0, binding = 3) uniform sampler2D specSampler;

layout (push_constant) uniform VP {
    mat4 view;
    mat4 projection;
} vp;

const vec3 lightPos = vec3(0.0, 0.0, 300.0);

const float lightIntensity = 1.0f;

const float shininess = 50.0;

void main()
{
    mat3 TBN = transpose(mat3(
        fragTan,
        fragBitan,
        fragNor
    ));

    vec3 normapFragNor = normalize(texture(normalSampler, fragUV).rgb * 2.0 - 1.0);

    vec3 lightDirectionTangSpace = TBN * (lightPos - fragPos);

    float dotProduct = dot(normalize(lightDirectionTangSpace), normalize(normapFragNor));

    float meshNormalDotProduct = dot(normalize(lightDirectionTangSpace), normalize(fragNor));

    float diffuse = min(max(dotProduct, 0.0), 1.0);


    float specular = pow(diffuse, shininess);

    vec4 texelColor = texture(textureSampler, fragUV);

    vec3 specularColor = vec3(texture(specSampler, fragUV));


    float specResultColorComponent = min(1.0, diffuse);

    outFragColor = vec4(diffuse * vec3(texelColor)  , texelColor.a); // For Spec Map: diffuse * vec3(texelColor) + (specular * specularColor)
}

Result: enter image description here

As it can be seen, the fragments on the whole mesh are shaded a bit fuzzy and noisy, specially on the arms.

Whenever i load this mesh with the same textures in Unity3D, the result is without the mentioned noises: enter image description here

Another model with normal map + spec map works like a charm, so this sounds paradoxical to me, since Unity3D can render both these three models correctly, but my program fails to generate lighting values only for a specific model, which implicates that the shader could interpret the data in textures/models! enter image description here

What could be the source of this problem?

[UPDATE]

After visualizing normals with geometry shader: enter image description here

chakmeshma
  • 246
  • 8
  • 27
  • 1
    It may be a problem with transformations, with vertex attributes, with data interpolation. Check each of the input data/vertex attributes separately and display them as a color. Then do the same for each step You perform in shaders. Think how they should look like and try to find which one is wrong. If You find out which data/operation/attribute is incorrect, it will be easier to find the source of Your problem. – Ekzuzy Nov 18 '17 at 21:41
  • 1
    @chakmeshma: Why would you make your model matrix a descriptor set variable, but your projection use push constants? The model matrix changes *far* more frequently than projection (which typically is the same for the entire scene). Push constants are for rapidly changing values. – Nicol Bolas Nov 21 '17 at 18:07
  • 1
    @chakmeshma: Did You try debugging Your problem the way I described above? Did You acquire any results, compared the working model with the one that doesn't work? You only shared Your shaders' code. Of course, it may be a problem in Your shaders, a hard to spot one. But it may also be caused by something else like mentioned above vertex attributes, input data format, problem with data transfer, data interpolation between shader stages. Without more information from You we may not be able to help You. – Ekzuzy Nov 23 '17 at 09:56
  • I suspect the unity model loader does some cleanup/magic to the actual model data, loading and reexporting the model in some other software may solve the issue. Also I find the provided screenshots to be too small / far away to properly see the artifacts or debug normals for that matter. – LJᛃ Nov 30 '17 at 16:58
  • @chakmeshma I see there was no update in this question for a long time. Did You resolve Your issue? Is yes, what was the problem? If no, did You try debugging the problem using the methods I described? – Ekzuzy Jan 08 '18 at 19:14

1 Answers1

2

Your transformations of normals (and potentialy the others) seem wrong to me. You typically don't transform using the same matrix as vertex. Inverse transpose is usually used.

Try visualising your normals with e.g. using geometry shader (emit lines).

krOoze
  • 12,301
  • 1
  • 20
  • 34
  • 3
    In fact using the same matrix for vertex and normals transformations is a valid behavior. We can do this if we only scale objects uniformly (the same scale is applied to all dimensions). If objects are not scaled uniformly than indeed inverse transpose is needed for normal transformations. But even if we did use the same matrix in this case, the result would look differently than the one seen above. – Ekzuzy Nov 23 '17 at 15:28