2
votes

I created two shaders for my program to render simple objects.

Vertex shader source:

#version 400 core
layout (location = 1) in vec4 i_vertexCoords;
layout (location = 2) in vec3 i_textureCoords;
layout (location = 3) in vec3 i_normalCoords;
layout (location = 4) in int i_material;

uniform mat4 u_transform;

out VertexData {
    vec3 textureCoords;
    vec3 normalCoords;
    int material;
} vs_out;

void main() {
    vs_out.textureCoords = i_textureCoords;
    vs_out.material = i_material;
    gl_Position = u_transform * i_vertexCoords;
    vs_out.normalCoords = gl_Position.xyz;
}

Fragment shader source:

#version 400 core
struct MaterialStruct {
    int ambientTexutre;
    int diffuseTexture;
    int specularTexture;
    int bumpTexture;

    vec4 ambientColor;
    vec4 diffuseColor;
    vec4 specularColor;

    float specularComponent;
    float alpha;
    int illuminationModel;
};

in VertexData {
    vec3 textureCoords;
    vec3 normalCoords;
    int material;
} vs_out;

layout (std140) uniform MaterialsBlock {
    MaterialStruct materials[8];
} u_materials;

uniform sampler2D u_samplers[16];

out vec4 fs_color;


void main() {
    MaterialStruct m = u_materials.materials[vs_out.material];
    fs_color = vec4(m.diffuseColor.rgb, m.diffuseColor.a * m.alpha);
}

Program created with this two shaders renders picture 2 axes When I change main() function contents to next:

void main() {
    MaterialStruct m = u_materials.materials[vs_out.material];
    fs_color = vec4(m.diffuseColor.rgb * (vs_out.normalCoords.z + 0.5), m.diffuseColor.a * m.alpha);
}

It renders picture 1, but materials still exists (if I'm trying to select material from u_materials.materials manually it works). Shader thinks what vs_out.material is constant and equals 0, but it isn't. Data is not changed (excluding transformation matrix) Could someone explain the solution of this problem?

1
Not sure I understand your comment Shader thinks what vs_out.material is constant and equals 0, but it isn't. The only change in the fragment shader appears to be the use of (vs_out.normalCoords.z + 0.5) as a multiplier in the colour calculation. Given that the colour appears to be bleached out in figure 1 is it possible that vs_out.normalCoords.z has some large value? - G.M.
Not sure what you expect from multiplying a color with a normal component + 0.5. Also, not sure of this on the vertex shader: vs_out.normalCoords = gl_Position.xyz;. That's certainly not a normal to the vertex. - MadEqua
vs_out.normalCoords is just a gl_Position of vertex in this shader pair. vs_out.normalCoords.z fits range [0.1 .. 0.9]. When I change vs_out.material in MaterialStruct m = u_materials.materials[vs_out.material] to explicit value (0, 1 or 2) full model changes color correspondingly to gray, red and white. The problem of shader is substitution of vs_out.material to 0 when compiling shaders. - Deedee Megadoodoo
Your shaders shouldn't even compile, since your int varying isn't declared as flat. - derhass
@derhass , I'm very thankful to you. I added flat qualifier to vs_out.material variable and now it works as it should. - Deedee Megadoodoo

1 Answers

2
votes

The GLSL 4.5 spec states in section 4.3.4 "Input Variables":

Fragment shader inputs that are signed or unsigned integers, integer vectors, or any double-precision floating-point type must be qualified with the interpolation qualifier flat.

You can't use interpolation with those types, and actually, your code shouldn't compile on a strict implementation.