title: Making a glow effect - Problems with alpha values
body: <p>I want to create a glow effect for my game. In order to keep this minimalistic let's say I want to glow an Image. :)</p>
  
  <p>Starting with this one:</p>
  
  <p><a href="https://i.stack.imgur.com/sddkf.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/sddkf.png" alt="default picture, no effect"></a></p>
  
  <p>To get something like this:<a href="https://i.stack.imgur.com/ERsrV.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/ERsrV.png" alt="desired output, picture with glow effect"></a></p>
  
  <p>It's a three step way. </p>
  
  <ul>
  <li>save all bright pixels from the scene (= luminescence)</li>
  <li>Apply a blur effect on those pixels (= blur)</li>
  <li>draw original picture and the blur texture ontop (= assemble)</li>
  </ul>
  
  <p>Step 1 and 3 are no Problem. The blur part just doesn't want to work correctly. </p>
  
  <p>Before I explain further, here's my luminescence result: <a href="https://i.stack.imgur.com/1yeVL.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/1yeVL.png" alt="the picture, but all darker pixels are transparent"></a>
  <em>(threshold = 0.67f)</em></p>
  
  <p>An now when I blur this, I get some unlucky results:<a href="https://i.stack.imgur.com/td5bW.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/td5bW.png" alt="enter image description here"></a>
  This black edge comes from the fact, that <em>any</em> transparent color is black <em><code>vec4(0.0, 0.0, 0.0, 0.0)</code></em>. It's not an unkown Problem within SFML/GLSL, and the suggestion was to use SFML's <code>sf::BlendMode</code> for this and multiply the <code>.rgb</code> value of the final pixel color in the fragment shader with its alpha value. So I did and now this my result:</p>
  
  <p><a href="https://i.stack.imgur.com/Al8P0.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/Al8P0.png" alt="blurred, but overall too dark, especially the edges"></a></p>
  
  <p>It's better, but definetely not good. The blur shader now also avarages out the surrounding pixels of the luminescence mask. After assembling it's just a blurry picture:</p>
  
  <p><a href="https://i.stack.imgur.com/4wgZQ.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/4wgZQ.png" alt="Blurry Picture, not even close to resemble a glow effect"></a>.. I tried "fixing" this in the shader files by checking if the pixel's alpha is zero. This way I don't value them when avaraging out. But since sf::BlendMode is activated, I don't know how alpha behaves now - So I deactivated the blendmode but I still have weird results. (at the very of this question I provided the code and a result from this attempt)</p>
  
  <hr>
  
  <p>none of my attempts to fix this work. I really could use some help here. Maybe I'm doing something fundamentally wrong in the shaders.. here's the full code -
  If you want to compile it, make a folder resources with the 2 Fragment shaders and the <a href="https://pixnio.com/architecture/city-downtown/urban-water-architecture-buildings-city-lights-evening" rel="nofollow noreferrer">background.jpg</a> (in 1280x720).</p>
  
  <p><em>luminescence.frag</em></p>
  
  <pre><code>#version 120
  
  uniform sampler2D texture;
  uniform float threshold;
  
  void main(void){
      vec3 current_color = texture2D(texture, gl_TexCoord[0].xy).rgb;
      vec4 pixel =  vec4(current_color.rgb, 0.0);
      float brightness = dot(current_color.rgb, vec3(0.2126, 0.7152, 0.0722));
      if (brightness &gt;= threshold){
          pixel = texture2D(texture, gl_TexCoord[0].xy);
      }
      gl_FragColor = pixel;
  }
  </code></pre>
  
  <p><em>boxblur.frag</em></p>
  
  <pre><code>#version 120
  
  uniform sampler2D texture;
  uniform float texture_inverse;
  uniform int blur_radius;
  uniform vec2 blur_direction;
  
  void main(void){
      vec4 sum = texture2D(texture, gl_TexCoord[0].xy);
  
      for (int i = 0; i &lt; blur_radius; ++i){
          sum += texture2D(texture, gl_TexCoord[0].xy + (i * texture_inverse) * blur_direction);
          sum += texture2D(texture, gl_TexCoord[0].xy - (i * texture_inverse) * blur_direction);
      }
      vec4 pixel = vec4(sum / (blur_radius * 2 + 1));
      pixel.rgb *= pixel.a;
      gl_FragColor = pixel;
  }
  </code></pre>
  
  <p><em>main.cpp</em></p>
  
  <pre><code>#include &lt;SFML/Graphics.hpp&gt;
  #include &lt;iostream&gt;
  #include &lt;exception&gt;
  
  void run() {
      const sf::Vector2f SIZE(1280, 720);
  
      sf::Texture background_tex;
      background_tex.loadFromFile("resources/background.jpg");
      sf::Sprite background(background_tex);
  
  
  
      sf::Shader luminescence;
      luminescence.loadFromFile("resources/luminescence.frag", sf::Shader::Fragment);
      luminescence.setUniform("texture", sf::Shader::CurrentTexture);
      luminescence.setUniform("threshold", 0.67f);
  
      sf::Shader blur;
      blur.loadFromFile("resources/boxblur.frag", sf::Shader::Fragment);
      blur.setUniform("texture", sf::Shader::CurrentTexture);
      blur.setUniform("texture_inverse", 1.0f / SIZE.x);
  
  
  
  
      sf::RenderStates shader_states;
      shader_states.blendMode = sf::BlendMode(sf::BlendMode::One, sf::BlendMode::OneMinusSrcAlpha);
  
  
  
      sf::ContextSettings context_settings;
      context_settings.antialiasingLevel = 12;
  
      //draws background
      sf::RenderTexture scene_render;
      scene_render.create(SIZE.x, SIZE.y, context_settings);
  
      //draws luminescence and blur
      sf::RenderTexture shader_render;
      shader_render.create(SIZE.x, SIZE.y, context_settings);
  
  
  
      sf::RenderWindow window(sf::VideoMode(SIZE.x, SIZE.y), "glsl fun", sf::Style::Default, context_settings);
  
      while (window.isOpen()) {
          sf::Event event;
          while (window.pollEvent(event)) {
              if (event.type == sf::Event::Closed) {
                  window.close();
              }
          }
  
          scene_render.clear();
          scene_render.draw(background);
          scene_render.display();
  
  
          //apply luminescence
          shader_states.shader = &amp;luminescence;
          shader_render.clear(sf::Color::Transparent);
          shader_render.draw(sf::Sprite(scene_render.getTexture()), shader_states);
          shader_render.display();
  
          //apply two pass gaussian blur 3 times to simulate gaussian blur.
          shader_states.shader = &amp;blur;
          float blur_radius = 30.0f;
          for (int i = 0; i &lt; 3; ++i) {
              blur.setUniform("blur_radius", static_cast&lt;int&gt;(blur_radius));
  
              //vertical blur
              blur.setUniform("blur_direction", sf::Glsl::Vec2(1.0, 0.0));
              shader_render.draw(sf::Sprite(shader_render.getTexture()), shader_states);
              shader_render.display();
  
              //horizontal blur
              blur.setUniform("blur_direction", sf::Glsl::Vec2(0.0, 1.0));
              shader_render.draw(sf::Sprite(shader_render.getTexture()), shader_states);
              shader_render.display();
  
              //decrease blur_radius to simulate a gaussian blur
              blur_radius *= 0.45f;
          }
  
          //assembly
          window.clear();
          window.draw(sf::Sprite(scene_render.getTexture()));
          window.draw(sf::Sprite(shader_render.getTexture()));
          window.display();
      }
  }
  
  int main() {
      try {
          run();
      }
      catch (std::exception e) {
          std::cerr &lt;&lt; "caught exception - - - " &lt;&lt; e.what() &lt;&lt; '\n';
          return 1;
      }
      return 0;
  }
  </code></pre>
  
  <hr>
  
  <p>This is the boxblur.frag where I tried to exclude zero alpha values: (I removed <code>shader_states.blendMode = sf::BlendMode(sf::BlendMode::One, sf::BlendMode::OneMinusSrcAlpha);</code>on line 29 in main.cpp of course):</p>
  
  <pre><code>#version 120
  
  uniform sampler2D texture;
  uniform float texture_inverse;
  uniform int blur_radius;
  uniform vec2 blur_direction;
  
  void main(void){
      float div = 0.0;
      vec4 sum = vec4(0.0, 0.0, 0.0, 0.0);
      vec4 temp_color = texture2D(texture, gl_TexCoord[0].xy);
      if (temp_color.a &gt; 0.0){
          sum += temp_color;
          div += 1.0;
      }
  
  
      for (int i = 0; i &lt; blur_radius; ++i){
          temp_color = texture2D(texture, gl_TexCoord[0].xy + (i * texture_inverse) * blur_direction);
          if (temp_color.a &gt; 0.0){
              sum += temp_color;
              div += 1.0;
          }
          temp_color = texture2D(texture, gl_TexCoord[0].xy - (i * texture_inverse) * blur_direction);
          if (temp_color.a &gt; 0.0){
              sum += temp_color;
              div += 1.0;
          }
      }
      vec4 pixel;
      if (div == 0.0){
          pixel = vec4(texture2D(texture, gl_TexCoord[0].xy).rgb, 0.0);
      }
      else{
          pixel = vec4(sum / div);
      }
      gl_FragColor = pixel;
  }
  </code></pre>
  
  <p>Resulting in:
  <a href="https://i.stack.imgur.com/H6xFm.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/H6xFm.png" alt="mostly bright values. but too blocky and not smooth at all"></a></p>
  
  <p>[I am using Visual Studio 2017 Community] - Thanks for any help!</p>