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

5
  • 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. Commented Nov 18, 2017 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. Commented Nov 21, 2017 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. Commented Nov 23, 2017 at 9: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. Commented Nov 30, 2017 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? Commented Jan 8, 2018 at 19:14

1 Answer 1

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).

Sign up to request clarification or add additional context in comments.

1 Comment

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.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.