Why normal mapping doesn't appear correctly?

68 views Asked by At

I'm applying bump mapping to a tree. When no normal mapping applied, it appears like this.

enter image description here

But when a normal texture is used, it turned out to be too aggressive as follow which is ugly.

enter image description here

I checked tangent data which should be fine. So I was wondering if it's because a wrong normal texture image is used.

enter image description here

Here is my vertex shader code:

            "#version 430                                       \n" + 
            "layout (location = 3) uniform mat4 mvMatrix;       \n" + 
            "layout (location = 4) uniform mat4 proMatrix;      \n" + 
            "uniform vec3 light_pos = vec3(100.0, 100.0, 100.0);\n" + 
            "                                                   \n" + 
            "layout (location = 0) in vec4 position;            \n" + 
            "layout (location = 1) in vec2 tc_in;               \n" + 
            "layout (location = 2) in vec3 normal;              \n" + 
            "layout (location = 5) in vec3 tangent;             \n" + 
            "layout (location = 10) in uint draw_id;            \n" + 
            "                                                   \n" + 
            "out VS_OUT                                         \n" + 
            "{                                                  \n" + 
            "   vec2 UV;                                        \n" + 
            "   vec3 L;                                         \n" + 
            "   vec3 V;                                         \n" + 
            "} vs_out;                                          \n" + 
            "                                                   \n" + 
            "void main(void)                                    \n" + 
            "{                                                  \n" + 
            "   vec4 P = mvMatrix * position;                   \n" + 
            "                                                   \n" + 
            "   vec3 N = normalize(mat3(mvMatrix) * normal);    \n" + 
            "   vec3 T = normalize(mat3(mvMatrix) * tangent);   \n" + 
            "   vec3 B = cross(N, T);                           \n" + 
            //" vs_out.L = light_pos - P.xyz;                   \n" + 
            "   vec3 Light = mat3(mvMatrix) * light_pos - P.xyz;\n" + 
            "   vs_out.L = normalize(vec3(dot(Light, T), dot(Light, B), dot(Light, N)));    \n" + 
            "                                                   \n" + 
            "   vec3 View = -P.xyz;                             \n" + 
            "   vs_out.V = normalize(vec3(dot(View, T), dot(View, B), dot(View, N)));   \n" + 
            "                                                   \n" + 
            "   vs_out.UV = tc_in;                              \n" + 
            "                                                   \n" + 
            "   gl_Position = proMatrix * P;                    \n" + 
            "}"

fs code:

            "#version 430                                       \n" + 
            "layout (binding = 0) uniform sampler2D tex_color;  \n" + 
            "layout (binding = 1) uniform sampler2D tex_normal; \n" + 
            "out vec4 color;                                    \n" + 
            "                                                   \n" + 
            "in VS_OUT                                          \n" + 
            "{                                                  \n" + 
            "   vec2 UV;                                        \n" + 
            "   vec3 L;                                         \n" + 
            "   vec3 V;                                         \n" + 
            "} fs_in;                                           \n" + 
            "                                                   \n" + 
            "void main(void)                                    \n" + 
            "{                                                  \n" + 
            //" vec3 ambient = texture(tex_color, fs_in.UV).xyz * 0.2;          \n" + 
            "   vec3 diffuse_albedo = texture(tex_color, fs_in.UV).rgb; \n" + 
            "   vec3 specular_albedo = vec3(0.7);               \n" + 
            "   float specular_power = 128.0;                   \n" + 
            "                                                   \n" + 
            "   vec3 N = normalize(texture(tex_normal, fs_in.UV).rgb * 2.0 - vec3(1.0));    \n" + 
            "   vec3 L = fs_in.L;                               \n" + 
            "   vec3 V = fs_in.V;                               \n" + 
            "   vec3 R = reflect(-L, N);                        \n" + 
            "                                                   \n" + 
            "   vec3 diffuse = max(dot(N, L), 0.0) * diffuse_albedo;    \n" + 
            "   vec3 specular = pow(max(dot(R, V), 0.0), specular_power) * specular_albedo; \n" + 
            "                                                   \n" + 
            "   color = vec4(diffuse, 1.0);\n" + //ambient +  + specular
            //" color = vec4(texture(tex_color, fs_in.UV).rgb * 0.6, 1.0);\n" + 
            "}"

drawing command:

        gl.glActiveTexture(GL4.GL_TEXTURE0);
        texture.bind(gl);

        gl.glActiveTexture(GL4.GL_TEXTURE1);
        bumpTexture.bind(gl);

        gl.glBindVertexArray(vaoBuff.get(0));
        gl.glMultiDrawElementsIndirect(...);
1

There are 1 answers

2
Nico Schertler On BEST ANSWER

Your texture is a height map. Not a normal map. You have two options: Replace the height map with a normal map (they are usually blueish). Or calculate the normal from the height map. This can be done like this:

float heightLeft   = textureOffset(tex_normal, fs_in.UV, ivec2(-1, 0)).r;
float heightRight  = textureOffset(tex_normal, fs_in.UV, ivec2( 1, 0)).r;
float heightBottom = textureOffset(tex_normal, fs_in.UV, ivec2( 0,-1)).r;
float heightTop    = textureOffset(tex_normal, fs_in.UV, ivec2( 0, 1)).r;
vec3 N = normalize(cross(vec3(2, 0, heightRight - heightLeft), 
                         vec3(0, 2, heightTop - heightBottom));