So I'm quite new to OpenGL/GLSL. I'm trying to make multitexturing and simple normal lighting work. Here is a Vertex shader:
#version 130
uniform mat4 transform;
in vec3 vertPos;
in vec2 texUV;
in vec3 vertNorm;
in uint thisLayer;
out vec2 fragTexCoord;
out vec3 fragNorm;
out float fragLayer;
void main()
{
gl_Position = transform * vec4(vertPos, 1.0f);
fragTexCoord = texUV;
fragLayer = float(thisLayer);
fragNorm = vertNorm;
}
... and here is Fragment shader:
#version 130
uniform sampler2DArray texArray;
uniform uint texCount;
uniform float rTime;
in vec2 fragTexCoord;
in vec3 fragNorm;
in float fragLayer;
out vec4 color;
void main()
{
float actual_layer = max(0, min(texCount - uint(1), floor(fragLayer + 0.5))); // Getting texture layer
vec3 texCoord = vec3(fragTexCoord, actual_layer);
color = texture(texArray, texCoord);
}
And it works fine:
Multiplying color.rbg by any constant works as expected:
color = texture(texArray, texCoord);
color.rgb *= vec3(0.5, 0.5, 0.5);
But if I try to multiply color.rgb by a normal, like this:
vec3 finalNorm = (normalize(fragNorm) + vec3(1,1,1))/vec3(2,2,2);
color = texture(texArray, texCoord);
color.rgb *= finalNorm;
The wall texture changes to the last texture in the array (the one on the top):
I have no idea why this happens. I normalize vertex normals and map their values into [0, 1] range, so colors will stay in [0, 1] range after multiplication as well. It is supposed to simply shift the colors intensity, like it did while multiplying by a constant, not change the texture itself, right? I am aware of the fact that this is not how you perform normal lighting, however, this is not the correct behavior as well, and I'm ripping my hair off as to why. Any help is appreciated. I will provide more info if needed.
EDIT: OS is Windows 10. GPU's: Intel HD 4600/Nvidia GTX 860M (happens on both of them). OpenGL version 4.3.0 build 20.19.15.4624.
Some additional info:
I use SOIL library to load data from PNG files. I use:
glTexImage3D(GL_TEXTURE_2D_ARRAY, 0, GL_RGBA, img_width, img_height, layer_count * 2, 0, GL_RGBA, GL_UNSIGNED_BYTE, 0);
to create a container for texture array, and use:
glTexSubImage3D(GL_TEXTURE_2D_ARRAY, 0, 0, 0, i, img_width, img_height, layer_count, GL_RGBA, GL_UNSIGNED_BYTE, data);
to load data into it. One issue I have with this is that glTexImage3D takes layer_count (the number of textures) multiplied by 2, and I have no idea why as well! Maybe this is somehow related to the issue I'm having above?