I'm writing a deferred rendering pipeline and my fragment shader looks like this:

#version 410

// Input vertex attributes (from vertex shader)
in vec2 fragTexCoord;
in vec3 fragNormal;
in vec3 fragPosition;
in mat3 worldToTangentSpace;

// Input uniform values
uniform sampler2D albedoMap;
uniform sampler2D normalMap;
uniform sampler2D metalMap;
uniform sampler2D roughnessMap;
uniform sampler2D occlusionMap;
uniform float metalnessFactor;
uniform float roughnessFactor;
uniform bool metalMapWithColor;

// output fragment color
layout(location = 0) out vec4 gbuffAlbedo;
layout(location = 1) out vec4 gbuffNormals;
layout(location = 2) out vec4 gbuffPositions;
layout(location = 3) out vec4 gbuffMetalRoughnessOcclusion;
layout(location = 4) out vec4 gbuffSpecular;

void main()
    // calculate normals
    vec3 normalColor = normalize((2.0 * texture(normalMap, fragTexCoord).rgb) - 1.0);
    normalColor.y *= -1;
    normalColor = normalize(worldToTangentSpace * normalColor);
    // calculate albedo color
    vec4 texelColor = texture(albedoMap, fragTexCoord);
    // get metal map value
    vec4 metalTextureColor = texture(metalMap, fragTexCoord);
    // calculate metalness factor
    float metalTextureValue = metalMapWithColor ? metalTextureColor.a : metalTextureColor.r;
    float metalValue = metalTextureValue * metalnessFactor;
    // get specular color
    vec4 specularColor = metalMapWithColor ? vec4(metalTextureColor.rgb, 1) : vec4(1,1,1,1);
    // calculate roughness factor
    float roughnessValue = texture(roughnessMap, fragTexCoord).r * roughnessFactor;
    // calculate occlusion
    float occlusionValue = texture(occlusionMap, fragTexCoord).r;
    // set gbuffer
    gbuffAlbedo = texelColor;
    gbuffNormals = vec4((normalColor + 1) * 0.5, 1);
    gbuffPositions = vec4(fragPosition, 1);
    gbuffMetalRoughnessOcclusion = vec4(metalValue, roughnessValue, occlusionValue, 1);
    gbuffSpecular = specularColor;

For some reason occlusionMap always return black pixels. I checked the uniform location that its not -1, so the uniform exists and don't optimized out, and I checked and the texture is set properly. However, its always black.

What made me realise its a sampler limit is that if I remove any other sampler, for example if I comment out the metal texture of albedo, suddenly the occlusion works and return the right pixel.

This is what it looks like with the full code (note the occlusion is black):

enter image description here

And this is what it looks like if I remove the albedo texture by setting it to vec4(1,1,1,1) - suddenly it works:

enter image description here

From what I read I should be able to use at least 16 textures. They are not so big and occlusion is only one channel. Why do I get one sampler removed?



1 Answer 1


The issue is caused by exceeding the maximum number of active samplers. Removing a texture allows the occlusion texture to work because the total number of active samplers decreases. Ensure proper enabling and binding of all textures within the limit. Consider combining textures.


You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .