<p>I've been following a guide to learn OpenGL, and I'm now learning how to do post-processing.
In particular, I'm trying to apply a blur to my rendering through the following kernel:</p>

<p>$\frac{\begin{bmatrix}1&amp;2&amp;1\\2&amp;4&amp;2\\1&amp;2&amp;1\end{bmatrix}}{16}$</p>

<p>The problem I'm encountering is that whenever I try to access a float array's member through the <code>[]</code> operator giving it an int variable as parameter, it returns <code>0.0</code>.
Here's my fragment shader:</p>

<pre><code>#version 410 core
in vec2 txcoords;  // Texture coordinates
out vec4 color;
uniform sampler2D tx;

const float offset = 1.0 / 300.0;

void main() {
    vec2 offsets[9] = vec2[](
        vec2(-offset,    offset),
        vec2( 0.0,       offset),
        vec2( offset,    offset),
        vec2(-offset,    0.0),
        vec2( 0.0,       0.0),
        vec2( offset,    0.0),
        vec2(-offset,   -offset),
        vec2( 0.0,      -offset),
        vec2( offset,   -offset)
    );

    const float kernel[9] = float[9](
        1.0 / 16, 2.0 / 16, 1.0 / 16,
        2.0 / 16, 4.0 / 16, 2.0 / 16,
        1.0 / 16, 2.0 / 16, 1.0 / 16
    );

    vec3 sampleTex[9];
    vec3 final = vec3(0.0);
    for (int i = 0; i &lt; 9; i++) {
        sampleTex[i] = vec3(texture(tx, txcoords.st + offsets[i]));
    }

    for (int i = 0; i &lt; 9; i++) {
        final += sampleTex[i] * kernel[i];
    }
    color = vec4(final, 1.0);
}
</code></pre>

<p>This code doesn't work(whole screen renders black), but if I change it to</p>

<pre><code>final += sampleTex[i] * kernel[0];
</code></pre>

<p>then my scene is rendered correctly, but, of course, without any blur, just a bit darker than normal.
It also doesn't just work with <code>kernel[0]</code>, but with any number (<code>[1]</code>, <code>[2]</code>, etc.)</p>

<p>If instead I change it to </p>

<pre><code>final += sampleTex[i] * (kernel[i] + 0.05);
</code></pre>

<p>then it renders exactly the same as with</p>

<pre><code>final += sampleTex[i] * 0.05;
</code></pre>

<p>And that's why I ended up suspecting that it's the <code>[i]</code> part that just won't work, for whatever reason.</p>

<p>Does anyone have any idea as to why this is happening? I also tried with different shader versions (330, 400, etc.) but they all give the same result.</p>

<p>Thanks for your time!</p>

CC BY-SA 3.0
2017-09-30T15:52:44.333Z
Minor optimization unrelated to your problem (but also circumventing it): your specific kernel can as well be achieved with just 4 texture accesses and an average of those 4 values. Just use a linearly filtered sampler and move the four texture coordinates by half a texel into the four corners of the current texel. You'll find that with normal linear filtering this will give you exactly the weighting specified in `kernel`.
Christian Rau
CC BY-SA 3.0
2017-07-21T14:13:34.777Z
What OpenGL version are you using, and is it WebGL or a real program?
Dan Hulme
CC BY-SA 3.0
2017-07-21T15:00:07.990Z
I'm using SDL2 to create a context for OpenGL 4.1. It's the regular version of OpenGL, not ES or WebGL
Daus
CC BY-SA 3.0
2017-07-21T23:21:30.023Z
In your `kernel` array you divide `float` by `int`. I suspect that for some reason your compiler cast this to `int`instead of `float`  so information is lost and then to `float`.
mdkdy
CC BY-SA 3.0
2017-07-22T01:56:57.510Z
Why don't you use the numerators from the kernel and divide the whole thing by 16.0 at the end just to see if it works?
user1118321
CC BY-SA 3.0
2017-07-22T08:55:11.543Z
I've tried both adding `.0` to the divisions by 16 and removing the division altogether, and even changing the kernel to another post-proc effect, but it still gives me the same results.
For now, my solution is to just unravel the loop and write all the steps manually. Would that be a good approach or a bad practice in a professional shader?
Daus
CC BY-SA 3.0
2017-07-25T04:23:04.013Z
I would find that odd, but if it works where a loop doesn't, go for it! It could be a bug in the glsl compiler or something. I'd add a comment explaining why you're doing.
user1118321
<opengl><glsl>
GLSL broken access operator
Daus
# GLSL broken access operator

(Asked by: username_0 on 2017-07-21)

I've been following a guide to learn OpenGL, and I'm now learning how to do post-processing.
In particular, I'm trying to apply a blur to my rendering through the following kernel:

$\frac{\begin{bmatrix}1&2&1\\2&4&2\\1&2&1\end{bmatrix}}{16}$

The problem I'm encountering is that whenever I try to access a float array's member through the `[]` operator giving it an int variable as parameter, it returns `0.0`.
Here's my fragment shader:

```
#version 410 core
in vec2 txcoords;  // Texture coordinates
out vec4 color;
uniform sampler2D tx;

const float offset = 1.0 / 300.0;

void main() {
    vec2 offsets[9] = vec2[](
        vec2(-offset,    offset),
        vec2( 0.0,       offset),
        vec2( offset,    offset),
        vec2(-offset,    0.0),
        vec2( 0.0,       0.0),
        vec2( offset,    0.0),
        vec2(-offset,   -offset),
        vec2( 0.0,      -offset),
        vec2( offset,   -offset)
    );

    const float kernel[9] = float[9](
        1.0 / 16, 2.0 / 16, 1.0 / 16,
        2.0 / 16, 4.0 / 16, 2.0 / 16,
        1.0 / 16, 2.0 / 16, 1.0 / 16
    );

    vec3 sampleTex[9];
    vec3 final = vec3(0.0);
    for (int i = 0; i < 9; i++) {
        sampleTex[i] = vec3(texture(tx, txcoords.st + offsets[i]));
    }

    for (int i = 0; i < 9; i++) {
        final += sampleTex[i] * kernel[i];
    }
    color = vec4(final, 1.0);
}

```

This code doesn't work(whole screen renders black), but if I change it to

```
final += sampleTex[i] * kernel[0];

```

then my scene is rendered correctly, but, of course, without any blur, just a bit darker than normal.
It also doesn't just work with `kernel[0]`, but with any number (`[1]`, `[2]`, etc.)

If instead I change it to

```
final += sampleTex[i] * (kernel[i] + 0.05);

```

then it renders exactly the same as with

```
final += sampleTex[i] * 0.05;

```

And that's why I ended up suspecting that it's the `[i]` part that just won't work, for whatever reason.

Does anyone have any idea as to why this is happening? I also tried with different shader versions (330, 400, etc.) but they all give the same result.

Thanks for your time!

**Tags:** opengl, glsl

> **Comments:**
> **username_2**: What OpenGL version are you using, and is it WebGL or a real program?  
> **username_0**: I'm using SDL2 to create a context for OpenGL 4.1. It's the regular version of OpenGL, not ES or WebGL  
> **username_3**: In your `kernel` array you divide `float` by `int`. I suspect that for some reason your compiler cast this to `int`instead of `float`  so information is lost and then to `float`.  
> **username_4**: Why don't you use the numerators from the kernel and divide the whole thing by 16.0 at the end just to see if it works?  
> **username_0**: I've tried both adding `.0` to the divisions by 16 and removing the division altogether, and even changing the kernel to another post-proc effect, but it still gives me the same results. For now, my solution is to just unravel the loop and write all the steps manually. Would that be a good approach or a bad practice in a professional shader?  
> **username_4**: I would find that odd, but if it works where a loop doesn't, go for it! It could be a bug in the glsl compiler or something. I'd add a comment explaining why you're doing.  
> **username_1**: Minor optimization unrelated to your problem (but also circumventing it): your specific kernel can as well be achieved with just 4 texture accesses and an average of those 4 values. Just use a linearly filtered sampler and move the four texture coordinates by half a texel into the four corners of the current texel. You'll find that with normal linear filtering this will give you exactly the weighting specified in `kernel`.  

---

## 0 answers

