<p>It should be significantly faster to sample one RGBA value from one location in a texture than four R values from different locations in the texture.</p>

CC BY-SA 4.0
2020-05-18T21:12:19.233Z
ok thank you for the clarity here - is it safe to assume then that if I had 4 texelFetch().r calls to the same location, this would be similar in speed to one texelFetch().rgba ?
Lucas Morgan
CC BY-SA 4.0
2020-05-20T00:25:29.713Z
I’d expect the separate fetches to be slower, as @Isolin said—packing the values into one texture should mean you’re making the best possible use of the hardware.
Noah Witherspoon
CC BY-SA 4.0
2020-05-18T20:59:05.390Z
2020-05-18T20:59:05.390Z
Noah Witherspoon
<p>I fully agree with all other replies and comments that <code>rgba</code> is definitely faster as it reduces the number of fetches from 16 to 4. You can even omit the per-element assignment:</p>

<pre class="lang-glsl prettyprint-override"><code>//I also fixed the typo in Matric[i]es
m[0] = texelFetch( projMatrices , ivec2( 0 , lightIndex ) , 0 );
m[1] = texelFetch( projMatrices , ivec2( 1 , lightIndex ) , 0 );
m[2] = texelFetch( projMatrices , ivec2( 2 , lightIndex ) , 0 );
m[3] = texelFetch( projMatrices , ivec2( 3 , lightIndex ) , 0 );
</code></pre>

CC BY-SA 4.0
2020-05-18T22:12:54.257Z
2020-05-18T22:12:54.257Z
Isolin
<p>I'm going through and optimizing some of my glsl code for a project, and have come across a scenario several times that I am not sure how best to optimize.</p>

<p>In summary - Is it faster to sample a texture once with <code>.rgba</code> vs 4 times with simply <code>.r</code> at the end?</p>

<p>Here's what I have now:</p>

<pre><code>mat4 getLightProjectionMatrix(int lightIndex){
    mat4 m;

    m[0][0] = texelFetch( projMatricies , ivec2( 0 , lightIndex ) , 0 ).r;
    m[0][1] = texelFetch( projMatricies , ivec2( 1 , lightIndex ) , 0 ).r;
    m[0][2] = texelFetch( projMatricies , ivec2( 2 , lightIndex ) , 0 ).r;
    m[0][3] = texelFetch( projMatricies , ivec2( 3 , lightIndex ) , 0 ).r;

    m[1][0] = texelFetch( projMatricies , ivec2( 4 , lightIndex ) , 0 ).r;
    m[1][1] = texelFetch( projMatricies , ivec2( 5 , lightIndex ) , 0 ).r;
    m[1][2] = texelFetch( projMatricies , ivec2( 6 , lightIndex ) , 0 ).r;
    m[1][3] = texelFetch( projMatricies , ivec2( 7 , lightIndex ) , 0 ).r;

    m[2][0] = texelFetch( projMatricies , ivec2( 8 , lightIndex ) , 0 ).r;
    m[2][1] = texelFetch( projMatricies , ivec2( 9 , lightIndex ) , 0 ).r;
    m[2][2] = texelFetch( projMatricies , ivec2( 10 , lightIndex ) , 0 ).r;
    m[2][3] = texelFetch( projMatricies , ivec2( 11 , lightIndex ) , 0 ).r;

    m[3][0] = texelFetch( projMatricies , ivec2( 12 , lightIndex ) , 0 ).r;
    m[3][1] = texelFetch( projMatricies , ivec2( 13 , lightIndex ) , 0 ).r;
    m[3][2] = texelFetch( projMatricies , ivec2( 14 , lightIndex ) , 0 ).r;
    m[3][3] = texelFetch( projMatricies , ivec2( 15 , lightIndex ) , 0 ).r;

    return m;
}
</code></pre>

<p>Here's what I'm considering doing:</p>

<pre><code>mat4 getLightProjectionMatrix(int lightIndex){
    mat4 m;

    vec4 A = texelFetch( projMatricies , ivec2( 0 , lightIndex ) , 0 ).rgba;
    m[0][0] = A[0];
    m[0][1] = A[1];
    m[0][2] = A[2];
    m[0][3] = A[3];

    vec4 B = texelFetch( projMatricies , ivec2( 0 , lightIndex ) , 0 ).rgba;
    m[1][0] = B[0];
    m[1][1] = B[1];
    m[1][2] = B[2];
    m[1][3] = B[3];

    vec4 C = texelFetch( projMatricies , ivec2( 0 , lightIndex ) , 0 ).rgba;
    m[2][0] = C[0];
    m[2][1] = C[1];
    m[2][2] = C[2];
    m[2][3] = C[3];

    vec4 D = texelFetch( projMatricies , ivec2( 0 , lightIndex ) , 0 ).rgba;
    m[3][0] = D[0];
    m[3][1] = D[1];
    m[3][2] = D[2];
    m[3][3] = D[3];

    return m;
}
</code></pre>

<p>Does the compiler know how to optimize both of these into the same thing in the end? or would it be more efficient to pack more data into a texture fetch no matter what?</p>

<p>Thanks!</p>

CC BY-SA 4.0
2020-05-18T21:04:25.197Z
The compiler can't optimize them both into the same thing, as they don't do the same thing. The way the texture is set up on the application side also has to be changed to match.
Nathan Reed
CC BY-SA 4.0
2020-05-18T21:08:24.960Z
True, I forgot to mention that I'd also be changing the format of the texture being sampled from to accommodate 4 texture calls vs 16.
Lucas Morgan
CC BY-SA 4.0
2020-05-18T21:35:31.770Z
Speaking of better optimization, why not set these matrices as uniforms?
mdkdy
<shader><texture><glsl><sampling>
What's more optimal - sampling one channel at a time or all channels at once?
Lucas Morgan
# What's more optimal - sampling one channel at a time or all channels at once?

(Asked by: username_0 on 2020-05-18)

I'm going through and optimizing some of my glsl code for a project, and have come across a scenario several times that I am not sure how best to optimize.

In summary - Is it faster to sample a texture once with `.rgba` vs 4 times with simply `.r` at the end?

Here's what I have now:

```
mat4 getLightProjectionMatrix(int lightIndex){
    mat4 m;

    m[0][0] = texelFetch( projMatricies , ivec2( 0 , lightIndex ) , 0 ).r;
    m[0][1] = texelFetch( projMatricies , ivec2( 1 , lightIndex ) , 0 ).r;
    m[0][2] = texelFetch( projMatricies , ivec2( 2 , lightIndex ) , 0 ).r;
    m[0][3] = texelFetch( projMatricies , ivec2( 3 , lightIndex ) , 0 ).r;

    m[1][0] = texelFetch( projMatricies , ivec2( 4 , lightIndex ) , 0 ).r;
    m[1][1] = texelFetch( projMatricies , ivec2( 5 , lightIndex ) , 0 ).r;
    m[1][2] = texelFetch( projMatricies , ivec2( 6 , lightIndex ) , 0 ).r;
    m[1][3] = texelFetch( projMatricies , ivec2( 7 , lightIndex ) , 0 ).r;

    m[2][0] = texelFetch( projMatricies , ivec2( 8 , lightIndex ) , 0 ).r;
    m[2][1] = texelFetch( projMatricies , ivec2( 9 , lightIndex ) , 0 ).r;
    m[2][2] = texelFetch( projMatricies , ivec2( 10 , lightIndex ) , 0 ).r;
    m[2][3] = texelFetch( projMatricies , ivec2( 11 , lightIndex ) , 0 ).r;

    m[3][0] = texelFetch( projMatricies , ivec2( 12 , lightIndex ) , 0 ).r;
    m[3][1] = texelFetch( projMatricies , ivec2( 13 , lightIndex ) , 0 ).r;
    m[3][2] = texelFetch( projMatricies , ivec2( 14 , lightIndex ) , 0 ).r;
    m[3][3] = texelFetch( projMatricies , ivec2( 15 , lightIndex ) , 0 ).r;

    return m;
}

```

Here's what I'm considering doing:

```
mat4 getLightProjectionMatrix(int lightIndex){
    mat4 m;

    vec4 A = texelFetch( projMatricies , ivec2( 0 , lightIndex ) , 0 ).rgba;
    m[0][0] = A[0];
    m[0][1] = A[1];
    m[0][2] = A[2];
    m[0][3] = A[3];

    vec4 B = texelFetch( projMatricies , ivec2( 0 , lightIndex ) , 0 ).rgba;
    m[1][0] = B[0];
    m[1][1] = B[1];
    m[1][2] = B[2];
    m[1][3] = B[3];

    vec4 C = texelFetch( projMatricies , ivec2( 0 , lightIndex ) , 0 ).rgba;
    m[2][0] = C[0];
    m[2][1] = C[1];
    m[2][2] = C[2];
    m[2][3] = C[3];

    vec4 D = texelFetch( projMatricies , ivec2( 0 , lightIndex ) , 0 ).rgba;
    m[3][0] = D[0];
    m[3][1] = D[1];
    m[3][2] = D[2];
    m[3][3] = D[3];

    return m;
}

```

Does the compiler know how to optimize both of these into the same thing in the end? or would it be more efficient to pack more data into a texture fetch no matter what?

Thanks!

**Tags:** shader, texture, glsl, sampling

> **Comments:**
> **username_1**: The compiler can't optimize them both into the same thing, as they don't do the same thing. The way the texture is set up on the application side also has to be changed to match.  
> **username_0**: True, I forgot to mention that I'd also be changing the format of the texture being sampled from to accommodate 4 texture calls vs 16.  
> **username_2**: Speaking of better optimization, why not set these matrices as uniforms?  

---

## 2 answers

### Answer by username_3 on 2020-05-18. Score: 3 | Accepted answer

It should be significantly faster to sample one RGBA value from one location in a texture than four R values from different locations in the texture.

> **Comments:**
> **username_0**: ok thank you for the clarity here - is it safe to assume then that if I had 4 texelFetch().r calls to the same location, this would be similar in speed to one texelFetch().rgba ?  
> **username_3**: I’d expect the separate fetches to be slower, as @username_4 said—packing the values into one texture should mean you’re making the best possible use of the hardware.  

---

### Answer by username_4 on 2020-05-18. Score: 3

I fully agree with all other replies and comments that `rgba` is definitely faster as it reduces the number of fetches from 16 to 4. You can even omit the per-element assignment:

```glsl
//I also fixed the typo in Matric[i]es
m[0] = texelFetch( projMatrices , ivec2( 0 , lightIndex ) , 0 );
m[1] = texelFetch( projMatrices , ivec2( 1 , lightIndex ) , 0 );
m[2] = texelFetch( projMatrices , ivec2( 2 , lightIndex ) , 0 );
m[3] = texelFetch( projMatrices , ivec2( 3 , lightIndex ) , 0 );

```


---

