<blockquote>
<p>Why can't I just select the texture unit directly into the shader source</p>
</blockquote>
<p><a href="https://www.khronos.org/opengl/wiki/Layout_Qualifier_(GLSL)#Binding_points" rel="nofollow noreferrer">You can:</a></p>
<pre><code>layout(binding = 0) uniform sampler2D texSampler;

void SomeFunction(vec2 coord)
{
    vec4 data = texture(texSampler, coord);
    // do something
}
</code></pre>
<p>Binding indices of course must be constant expressions.</p>
<p>As for why you can't just use a number directly... how would GLSL know what <em>kind</em> of texture you're talking about? <a href="https://www.khronos.org/opengl/wiki/Sampler_(GLSL)#Sampler_types" rel="nofollow noreferrer">GLSL samplers are typed</a>, in accord with the kind of texture being accessed. This is important, as it also changes what parameters <code>texture</code> takes. If you're accessing a 1D texture, <code>texture</code> takes a single float as a texture coordinate. If you're accessing a cubemap, it takes a <code>vec3</code>. Etc.</p>
<p>This is important for many reasons. One of them being that the logic for doing the fetch is often part of the <em>shader</em> itself. A shadow sampler might do the conditional logic within the shader. That wouldn't be possible if the GLSL didn't specify that it was doing a comparison test.</p>
<p>Note that even <a href="https://www.khronos.org/opengl/wiki/Bindless_Texture#Purpose" rel="nofollow noreferrer">bindless textures</a>, where you pass an integer that represents a texture object to the shader, still requires that you <a href="https://www.khronos.org/opengl/wiki/Bindless_Texture#Handles_as_integers" rel="nofollow noreferrer">convert the integer handle for the texture into a specific sampler type</a>.</p>

CC BY-SA 4.0
2022-06-24T15:56:23.333Z
2022-06-24T15:56:23.333Z
Nicol Bolas
<p>To use a texture in an OpenGL shader, I have to write the Texture Unit to be used into a uniform variable:</p>
<p><strong>source.c:</strong></p>
<pre><code>// Write 0 to uniform variable
GLuint texSampler = glGetUniformLocation(program, &quot;texSampler&quot;);
glUniform1i(texSampler, 0);
</code></pre>
<p><strong>shader.glsl</strong></p>
<pre><code>uniform sampler2D texSampler;

void SomeFunction(vec2 coord)
{
    vec4 data = texture(texSampler, coord);
    // do something
}
</code></pre>
<p>Why can't I just select the texture unit directly into the shader source, like this?</p>
<p><strong>shader.glsl</strong></p>
<pre><code>void SomeFunction(vec2 coord)
{
    vec4 data = texture(0, coord);
    // do something
}
</code></pre>
<p>What is the architecturial reason, that I have to use a uniform variable to pass the texture unit into the shader?</p>

<opengl><glsl>
Why must texture samplers be uniform variables in GLSL?
Mario
# Why must texture samplers be uniform variables in GLSL?

(Asked by: username_0 on 2022-06-24)

To use a texture in an OpenGL shader, I have to write the Texture Unit to be used into a uniform variable:
source.c:
// Write 0 to uniform variable
GLuint texSampler = glGetUniformLocation(program, "texSampler");
glUniform1i(texSampler, 0);

shader.glsl
uniform sampler2D texSampler;

void SomeFunction(vec2 coord)
{
    vec4 data = texture(texSampler, coord);
    // do something
}

Why can't I just select the texture unit directly into the shader source, like this?
shader.glsl
void SomeFunction(vec2 coord)
{
    vec4 data = texture(0, coord);
    // do something
}

What is the architecturial reason, that I have to use a uniform variable to pass the texture unit into the shader?

**Tags:** opengl, glsl

---

## 1 answers

### Answer by username_1 on 2022-06-24. Score: 4 | Accepted answer

Why can't I just select the texture unit directly into the shader source

You can:
layout(binding = 0) uniform sampler2D texSampler;

void SomeFunction(vec2 coord)
{
    vec4 data = texture(texSampler, coord);
    // do something
}

Binding indices of course must be constant expressions.
As for why you can't just use a number directly... how would GLSL know what kind of texture you're talking about? GLSL samplers are typed, in accord with the kind of texture being accessed. This is important, as it also changes what parameters texture takes. If you're accessing a 1D texture, texture takes a single float as a texture coordinate. If you're accessing a cubemap, it takes a vec3. Etc.
This is important for many reasons. One of them being that the logic for doing the fetch is often part of the shader itself. A shadow sampler might do the conditional logic within the shader. That wouldn't be possible if the GLSL didn't specify that it was doing a comparison test.
Note that even bindless textures, where you pass an integer that represents a texture object to the shader, still requires that you convert the integer handle for the texture into a specific sampler type.


---

