<p>It looks like you're drawing with pre-multiplied alpha. This means that the red, green, and blue channels have been multiplied by the alpha channel. So your shader should look more like this:</p>

<pre><code>precision mediump float;
uniform sampler2D uSampler;
varying vec2 vTextureCoord;
void main() {
    vec4 originalColor = texture2D(uSampler, vTextureCoord);
    vec4 tempColor = originalColor + vec4(0, 0, 0, -0.5);
    tempColor.rgb *=  tempColor.a;
    gl_FragColor = tempColor;
}
</code></pre>

<p>I believe you also need to set <code>glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)</code> to get the correct blending (and of course, <code>glEnable(GL_BLEND)</code>).</p>

CC BY-SA 4.0
2018-12-10T18:17:05.820Z
Thank you, sir, it works as expected. One question - why the DST equation is `GL_ONE_MINUS_SRC_ALPHA`? It looks to me that the fragment shader already performs required computation, so it should not be any further changed?
Aleksandr Medvedev
CC BY-SA 4.0
2018-12-11T02:11:47.220Z
The destination is for blending the results of your fragment shader with whatever is already in the framebuffer. So it happens after your fragment shader runs. Your fragment shader isn't touching the destination in any way.
user1118321
CC BY-SA 4.0
2018-12-13T03:58:03.620Z
The Dreams Wind: The source.rgb * source.alpha is already computed in your texture. You still need to blend it with your destination. The full blending formula becomes   frag = source.rgb + dest.rgb * (1-source.a); because source.rgb is "pre-multipled" already, saving your GPU some calculation. That is what the glBlendFunc is doing.
PaulHK
CC BY-SA 4.0
2018-12-10T06:28:04.183Z
2018-12-10T06:28:04.183Z
user1118321
<p>I'm looking for a way to make my surface semitransparent, and for now i ended up using this configuration:</p>

<pre><code>eglChooseConfig(eglDisplay, new int[] {
            EGL10.EGL_ALPHA_SIZE,   8,
            EGL10.EGL_RED_SIZE,     8,
            EGL10.EGL_GREEN_SIZE,   8,
            EGL10.EGL_BLUE_SIZE,    8,
            EGL10.EGL_NONE
}
</code></pre>

<p>My default configuration was:</p>

<pre><code>eglChooseConfig(eglDisplay, new int[] {
            EGL10.EGL_RED_SIZE,     8,
            EGL10.EGL_GREEN_SIZE,   8,
            EGL10.EGL_BLUE_SIZE,    8,
            EGL10.EGL_DEPTH_SIZE    16,
            EGL10.EGL_NONE
}
</code></pre>

<p>As you can see, i added EGL_ALPHA_SIZE attribute and removed EGL_DEPTH_SIZE, since my application is a simple 2D drawing on a surface and it doesn't need a depth buffer. It works, but for some reason results in somewhat unexpected results for this simple fragment shader:</p>

<pre><code>precision mediump float;
uniform sampler2D uSampler;
varying vec2 vTextureCoord;
void main() {
    vec4 originalColor = texture2D(uSampler, vTextureCoord);
    gl_FragColor = originalColor + vec4(0, 0, 0, -0.5);
}
</code></pre>

<p>The alpha component seems to be affecting rest of the parts of the color and changes it at some extent. The first image below is the original one, second is what I have, and the last one is what I want to achieve.</p>

<p><a href="https://i.sstatic.net/FigTB.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/FigTB.png" alt="Original image"></a>
<a href="https://i.sstatic.net/A6Pmq.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/A6Pmq.png" alt="What i have"></a>
<a href="https://i.sstatic.net/WQwMt.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/WQwMt.png" alt="What i want to achieve"></a></p>

<p>Any advice is appreciated, thanks!</p>

<h3>For the sake of clarity</h3>

<p>OpenGL ES Version: 2.0</p>

CC BY-SA 4.0
2018-12-10T00:30:13.997Z
"*The alpha component seems to be affecting rest of the parts of the color and changes it at some extent.*" How are you detecting those changes? That is, how do you know that the color is being changed? Have you read the pixels back? Or is this what you're seeing in some window? If it's a window, which OS and windowing compositor are you using? Is it one that supports transparency natively?
Nicol Bolas
CC BY-SA 4.0
2018-12-10T02:23:50.477Z
What blend mode are you using, this looks like a case of pre-multiplied alpha.
PaulHK
<glsl><opengl-es><fragment-shader>
Alpha component in color buffer affects RGB components?
Aleksandr Medvedev
# Alpha component in color buffer affects RGB components?

(Asked by: username_0 on 2018-12-09)

I'm looking for a way to make my surface semitransparent, and for now i ended up using this configuration:

```
eglChooseConfig(eglDisplay, new int[] {
            EGL10.EGL_ALPHA_SIZE,   8,
            EGL10.EGL_RED_SIZE,     8,
            EGL10.EGL_GREEN_SIZE,   8,
            EGL10.EGL_BLUE_SIZE,    8,
            EGL10.EGL_NONE
}

```

My default configuration was:

```
eglChooseConfig(eglDisplay, new int[] {
            EGL10.EGL_RED_SIZE,     8,
            EGL10.EGL_GREEN_SIZE,   8,
            EGL10.EGL_BLUE_SIZE,    8,
            EGL10.EGL_DEPTH_SIZE    16,
            EGL10.EGL_NONE
}

```

As you can see, i added EGL\_ALPHA\_SIZE attribute and removed EGL\_DEPTH\_SIZE, since my application is a simple 2D drawing on a surface and it doesn't need a depth buffer. It works, but for some reason results in somewhat unexpected results for this simple fragment shader:

```
precision mediump float;
uniform sampler2D uSampler;
varying vec2 vTextureCoord;
void main() {
    vec4 originalColor = texture2D(uSampler, vTextureCoord);
    gl_FragColor = originalColor + vec4(0, 0, 0, -0.5);
}

```

The alpha component seems to be affecting rest of the parts of the color and changes it at some extent. The first image below is the original one, second is what I have, and the last one is what I want to achieve.

[![Original image](https://i.sstatic.net/FigTB.png)](https://i.sstatic.net/FigTB.png)
[![What i have](https://i.sstatic.net/A6Pmq.png)](https://i.sstatic.net/A6Pmq.png)
[![What i want to achieve](https://i.sstatic.net/WQwMt.png)](https://i.sstatic.net/WQwMt.png)

Any advice is appreciated, thanks!

### For the sake of clarity

OpenGL ES Version: 2.0

**Tags:** glsl, opengl-es, fragment-shader

> **Comments:**
> **username_1**: "*The alpha component seems to be affecting rest of the parts of the color and changes it at some extent.*" How are you detecting those changes? That is, how do you know that the color is being changed? Have you read the pixels back? Or is this what you're seeing in some window? If it's a window, which OS and windowing compositor are you using? Is it one that supports transparency natively?  
> **username_2**: What blend mode are you using, this looks like a case of pre-multiplied alpha.  

---

## 1 answers

### Answer by username_3 on 2018-12-10. Score: 2 | Accepted answer

It looks like you're drawing with pre-multiplied alpha. This means that the red, green, and blue channels have been multiplied by the alpha channel. So your shader should look more like this:

```
precision mediump float;
uniform sampler2D uSampler;
varying vec2 vTextureCoord;
void main() {
    vec4 originalColor = texture2D(uSampler, vTextureCoord);
    vec4 tempColor = originalColor + vec4(0, 0, 0, -0.5);
    tempColor.rgb *=  tempColor.a;
    gl_FragColor = tempColor;
}

```

I believe you also need to set `glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA)` to get the correct blending (and of course, `glEnable(GL_BLEND)`).

> **Comments:**
> **username_0**: Thank you, sir, it works as expected. One question - why the DST equation is `GL_ONE_MINUS_SRC_ALPHA`? It looks to me that the fragment shader already performs required computation, so it should not be any further changed?  
> **username_3**: The destination is for blending the results of your fragment shader with whatever is already in the framebuffer. So it happens after your fragment shader runs. Your fragment shader isn't touching the destination in any way.  
> **username_2**: The Dreams Wind: The source.rgb * source.alpha is already computed in your texture. You still need to blend it with your destination. The full blending formula becomes   frag = source.rgb + dest.rgb * (1-source.a); because source.rgb is "pre-multipled" already, saving your GPU some calculation. That is what the glBlendFunc is doing.  

---

