<p><strong>Background:</strong></p>
<p>I am extracting the textures for a model with Assimp and sampling those textures in the fragment shader.  I have multiple <code>uniform sampler2D textureN</code> declarations in my fragment shader and call <code>glUniform1i(location, textureN)</code>, <code>glActiveTexture(GL_TEXTUREN)</code> and <code>glBindTexture(GL_TEXTURE_2D, textureN_ref)</code> for each texture.  This is working correctly.</p>
<p>The following Mesh drawing function from <a href="https://learnopengl.com/Model-Loading/Mesh" rel="nofollow noreferrer">learnopengl.com</a> binds multiple textures.  However, as shown below, the fragment shader only contains one sampler.</p>
<pre><code>void Draw(Shader &amp;shader) 
{
    unsigned int diffuseNr = 1;
    unsigned int specularNr = 1;
    for(unsigned int i = 0; i &lt; textures.size(); i++)
    {
        glActiveTexture(GL_TEXTURE0 + i); // activate proper texture unit before binding
        // retrieve texture number (the N in diffuse_textureN)
        string number;
        string name = textures[i].type;
        if(name == &quot;texture_diffuse&quot;)
            number = std::to_string(diffuseNr++);
        else if(name == &quot;texture_specular&quot;)
            number = std::to_string(specularNr++);

        shader.setFloat((&quot;material.&quot; + name + number).c_str(), i);
        glBindTexture(GL_TEXTURE_2D, textures[i].id);
    }
    glActiveTexture(GL_TEXTURE0);

    // draw mesh
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}
</code></pre>
<p>Fragment shader:</p>
<pre><code>#version 330 core
out vec4 FragColor;

in vec2 TexCoords;

uniform sampler2D texture_diffuse1;

void main()
{    
    FragColor = texture(texture_diffuse1, TexCoords);
}
</code></pre>
<p><strong>Question:</strong></p>
<p>Surely for the <code>void Draw(Shader &amp;shader)</code> function to work you would have to define multiple samplers in the fragment shader?  The linked article does in fact seem to state this in the paragraph prior to the function.</p>
<p>Thanks.</p>

CC BY-SA 4.0
2021-02-05T17:15:44.103Z
"*The linked article does in fact seem to state this in the paragraph prior to the function.*" So... what's the problem?
Nicol Bolas
CC BY-SA 4.0
2021-02-06T09:21:07.663Z
Thanks for the reply.  The actual shader used in the tutorial (shown above) doesn't follow the advice given in that paragraph.  This seems contradictory?
MasterReDWinD
CC BY-SA 4.0
2021-02-06T14:34:06.800Z
Yes, it does. When I go to that page and search for "sampler", I see a shader that has 5 sampler variables in it.
Nicol Bolas
CC BY-SA 4.0
2021-02-06T15:57:26.033Z
That's true, in the text of the article he does describe a shader with 5 samplers but then two articles further on (titled 'Model') when we actually get the complete ('model_loading.cpp') code he creates the fragment shader ('1.model_loading.fs') with the conents shown above.  I would have expected to see a fragment shader with the 5 samplers in.
MasterReDWinD
<opengl><shader><texture><c++>
Using multiple textures in a shader
MasterReDWinD
# Using multiple textures in a shader

(Asked by: username_0 on 2021-02-04)

**Background:**

I am extracting the textures for a model with Assimp and sampling those textures in the fragment shader. I have multiple `uniform sampler2D textureN` declarations in my fragment shader and call `glUniform1i(location, textureN)`, `glActiveTexture(GL_TEXTUREN)` and `glBindTexture(GL_TEXTURE_2D, textureN_ref)` for each texture. This is working correctly.

The following Mesh drawing function from [learnopengl.com](https://learnopengl.com/Model-Loading/Mesh) binds multiple textures. However, as shown below, the fragment shader only contains one sampler.

```
void Draw(Shader &shader) 
{
    unsigned int diffuseNr = 1;
    unsigned int specularNr = 1;
    for(unsigned int i = 0; i < textures.size(); i++)
    {
        glActiveTexture(GL_TEXTURE0 + i); // activate proper texture unit before binding
        // retrieve texture number (the N in diffuse_textureN)
        string number;
        string name = textures[i].type;
        if(name == "texture_diffuse")
            number = std::to_string(diffuseNr++);
        else if(name == "texture_specular")
            number = std::to_string(specularNr++);

        shader.setFloat(("material." + name + number).c_str(), i);
        glBindTexture(GL_TEXTURE_2D, textures[i].id);
    }
    glActiveTexture(GL_TEXTURE0);

    // draw mesh
    glBindVertexArray(VAO);
    glDrawElements(GL_TRIANGLES, indices.size(), GL_UNSIGNED_INT, 0);
    glBindVertexArray(0);
}

```

Fragment shader:

```
#version 330 core
out vec4 FragColor;

in vec2 TexCoords;

uniform sampler2D texture_diffuse1;

void main()
{    
    FragColor = texture(texture_diffuse1, TexCoords);
}

```

**Question:**

Surely for the `void Draw(Shader &shader)` function to work you would have to define multiple samplers in the fragment shader? The linked article does in fact seem to state this in the paragraph prior to the function.

Thanks.

**Tags:** opengl, shader, texture, c++

> **Comments:**
> **username_1**: "*The linked article does in fact seem to state this in the paragraph prior to the function.*" So... what's the problem?  
> **username_0**: Thanks for the reply.  The actual shader used in the tutorial (shown above) doesn't follow the advice given in that paragraph.  This seems contradictory?  
> **username_1**: Yes, it does. When I go to that page and search for "sampler", I see a shader that has 5 sampler variables in it.  
> **username_0**: That's true, in the text of the article he does describe a shader with 5 samplers but then two articles further on (titled 'Model') when we actually get the complete ('model_loading.cpp') code he creates the fragment shader ('1.model_loading.fs') with the conents shown above.  I would have expected to see a fragment shader with the 5 samplers in.  

---

## 0 answers

