If I have the following shader sources:
// vertex shader
#version 460 core
layout (location = 0) in vec2 inPos;
layout (location = 1) in vec2 inNorm;
uniform mat3 proj;
layout(binding = 0, std430) readonly buffer transformSSBO {
mat4 transforms[];
};
void main()
{
vec3 outPos = proj * mat3(transforms[gl_InstanceID]) * vec3(inPos, 1.0);
gl_Position = vec4(outPos.x, outPos.y, 0.0, 1.0);
}
// fragment shader
layout(binding = 1, std430) readonly buffer teamSSBO {
uint team[];
};
out vec4 FragColor;
void main()
{
int instanceID = 0;
uint teamVal = team[instanceID];
FragColor = vec4(float(teamVal) * 1.0f, 0.0f, float(1 - teamVal) * 1.0f, 1.0f);
}
Things seem to work as I would expect. But when I add an output variable, instanceID
to the vertex shader, and a matching input variable to the fragment shader, like so:
// vertex shader
#version 460 core
layout (location = 0) in vec2 inPos;
layout (location = 1) in vec2 inNorm;
uniform mat3 proj;
layout(binding = 0, std430) readonly buffer transformSSBO {
mat4 transforms[];
};
out int instanceID;
void main()
{
vec3 outPos = proj * mat3(transforms[gl_InstanceID]) * vec3(inPos, 1.0);
gl_Position = vec4(outPos.x, outPos.y, 0.0, 1.0);
instanceID = gl_InstanceID;
}
// fragment shader
#version 460 core
in int instanceID;
layout(binding = 1, std430) readonly buffer teamSSBO {
uint team[];
};
out vec4 FragColor;
void main()
{
uint teamVal = team[instanceID];
FragColor = vec4(float(teamVal) * 1.0f, 0.0f, float(1 - teamVal) * 1.0f, 1.0f);
}
OpenGL then tells me there are no active uniforms, and I cannot get the location for proj
. As far as I can tell, proj
is definitely needed to calculate gl_Position
, and so shouldn't be optimised away.
I have no glsl compilation errors. Does anyone have any hints as to what is going on here?
I would expect the shader program to not compile due to the flat
qualifier missing in this line in the fragment shader:
in int instanceID;
From the GLSL 4.60.8 specification:
Fragment shader inputs that are, or contain, integral or double-precision floating-point types must be qualified with the interpolation qualifier flat.
When this qualifier is left out, GLSL defaults to using smooth
interpolation, which isn't supported for integral types, hence the error. And since there is an error, there are no active uniforms.
By using the flat
qualifier, no interpolation is applied and the same value is used for every fragment of that primitive. The actual value is taken from the provoking vertex.