I'm working on an OpenGL application and my shader binaries compiler properly, but fail to link and I can't find a reason. They only fail on my integrated Intel drivers, no warnings or errors occur in Nvidia. It fails to link when I add a third output to my shader. So my essential questions are:
- Why is the linker failing when I add three or more outputs (the third being buffer2)
- How to find linker errors like these in the future at compile time, or give the reason for the error at least!
I'm using spirv-cross and shaderc to convert a vulkan shader to an opengl shader to an opengl binary.
My debug won't give me any info either:
---------------
Debug message (1): SHADER_ID_LINK error has been generated. GLSL link failed for program 1, "Test Shader":
Source: Shader Compiler
Type: Error
Severity: high
---------------
Debug message (1282): Error has been generated. GL error GL_INVALID_OPERATION in UseProgram: (ID: 1001309929) Generic error
Source: API
Type: Error
Severity: high
I've posted my code in a gist as well as below. https://gist.github.com/KarimIO/e6b9716ce491cfdfe74196e426376bf5
Vertex Shader:
#version 450
layout(binding = 0, std140) uniform EngineUbo
{
mat4 proj;
mat4 view;
mat4 model;
} ubo;
layout(location = 0) in vec3 vertexPosition;
layout(location = 0) out vec3 fragmentPosition;
layout(location = 1) out vec3 fragmentNormal;
layout(location = 1) in vec3 vertexNormal;
layout(location = 2) out vec3 fragmentTangent;
layout(location = 2) in vec3 vertexTangent;
layout(location = 3) out vec2 fragmentTexCoord0;
layout(location = 3) in vec2 vertexTexCoord0;
void main()
{
vec4 posVec4 = ubo.model * vec4(vertexPosition, 1.0);
gl_Position = (ubo.proj * ubo.view) * posVec4;
fragmentPosition = posVec4.xyz;
fragmentNormal = vertexNormal;
fragmentTangent = vertexTangent;
fragmentTexCoord0 = vertexTexCoord0;
}
Fragment Shader:
#version 450
layout(binding = 1, std140) uniform MaterialUbo
{
vec4 color;
} materialUbo;
layout(binding = 2) uniform sampler2D albedoTexture;
layout(binding = 3) uniform sampler2D normalTexture;
layout(binding = 4) uniform sampler2D metalnessTexture;
layout(binding = 5) uniform sampler2D roughnessTexture;
layout(location = 3) in vec2 fragmentTexCoord0;
layout(location = 1) in vec3 fragmentNormal;
layout(location = 2) in vec3 fragmentTangent;
layout(location = 0) out vec4 gbuffer0;
layout(location = 0) in vec3 fragmentPosition;
layout(location = 1) out vec4 gbuffer1;
layout(location = 2) out vec4 gbuffer2;
vec3 TransformNormalToWorldSpace(vec3 vertexNormalValue, vec3 normalTextureSample, vec3 vertexTangentValue)
{
vec3 bumpMapNormal = normalTextureSample;
if (all(equal(normalTextureSample, vec3(0.0))))
{
return vertexNormalValue;
}
vec3 newNormal = normalize(vertexNormalValue);
vec3 newTangent = normalize(vertexTangentValue);
newTangent = normalize(newTangent - (newNormal * dot(newTangent, newNormal)));
vec3 bitangent = cross(newTangent, newNormal);
bumpMapNormal = (bumpMapNormal * 2.0) - vec3(1.0);
bumpMapNormal = vec3(-bumpMapNormal.xy, bumpMapNormal.z);
mat3 tangentBitangentNormalMatrix = mat3(vec3(newTangent), vec3(bitangent), vec3(newNormal));
return normalize(tangentBitangentNormalMatrix * bumpMapNormal);
}
void main()
{
vec4 albedo = materialUbo.color * texture(albedoTexture, fragmentTexCoord0);
vec3 textureSpaceNormal = texture(normalTexture, fragmentTexCoord0).xyz;
float metalness = texture(metalnessTexture, fragmentTexCoord0).x;
float roughness = texture(roughnessTexture, fragmentTexCoord0).x;
vec3 specular = mix(vec3(0.039999999105930328369140625), albedo.xyz, vec3(metalness));
vec3 param = fragmentNormal;
vec3 param_1 = textureSpaceNormal;
vec3 param_2 = fragmentTangent;
vec3 worldSpaceNormal = TransformNormalToWorldSpace(param, param_1, param_2);
gbuffer0 = vec4(fragmentPosition, 1.0);
gbuffer1 = vec4(worldSpaceNormal, 1.0);
gbuffer2 = albedo;
}