5
\$\begingroup\$

I am trying to achieve additive blending with point sprites. When the sprites overlap, all I get is solid red, when I expect to get a smooth blend from red->yellow->white. My sprite texture has all four channels set equal, with portions being white and others transparent.

I set up blending as such:

  glEnable(GL_BLEND);
  glBlendFunc(GL_ONE, GL_ONE);

My fragment shader is as follows:

  vec4 texCol = texture(pointsprite, gl_PointCoord);
  colorOut = vec4(texCol.rgb * vec4(ocolor, 1.0).rgb, texCol.a);

Where pointsprite is a sampler2D and ocolor is `(1.0, 0.0, 0.0)

My background is cleared as

  glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

I have tried some of the various methods suggested in this question, none offering any results. I can verify my alpha channel is correctly loaded from my image into my texture.

EDIT: Missed mentioning that my intention is for clusters of point sprites with the same pigment (red) to additive blend to yellow and white.

\$\endgroup\$
6
  • \$\begingroup\$ Can you post a screenshot of the results you're currently getting, and clarify what you're trying to achieve? It's not obvious to me from your description what is the result you actually want. (BTW, with additive blending, the alpha channel doesn't affect the RGB at all.) \$\endgroup\$ Commented Jul 31, 2013 at 20:20
  • \$\begingroup\$ "When the sprites overlap, all I get is solid red." And... what exactly do you expect to get? Because, unless you're rendering to a high-dynamic range framebuffer, additive blending is almost always the wrong thing to do. So why do you want additive blending? \$\endgroup\$ Commented Jul 31, 2013 at 20:37
  • \$\begingroup\$ @NicolBolas in my situation, additive blending is definitely what I want. Should I use HDR? \$\endgroup\$
    – Outurnate
    Commented Jul 31, 2013 at 22:56
  • 1
    \$\begingroup\$ RED + RED = RED, never yellow. (1,0,0)red+(1,0,0)red=(2,0,0)very red. GL_ONE doesn't say to swap the color channels. You would need to experiment with GL_SRC_COLOR but it will probably be difficult to get the effect you want. Unfortunately fragment shaders don't make it easy to access previously rendered fragments -- except via framebuffer. \$\endgroup\$
    – bobobobo
    Commented Jul 31, 2013 at 23:00
  • \$\begingroup\$ I'm quite curious why you expect additive blending of red colors to go to yellow and white. I think it would help to see your thought process. Is it because you see white as what you get when you add all color together, and you see yellow as halfway between red and white? You need red, green, and blue added together to end up with white - not just red. Also, yellow is not a lighter red. A lighter red is a pinkish color. Yellow is in fact what you get if you mix red and green light together. \$\endgroup\$ Commented Aug 18, 2013 at 10:22

3 Answers 3

9
\$\begingroup\$

You can achieve the effect you are looking for by setting the color value to non-pure red. In the picture below I have drawn a circle with additive blending multiple times with small offsets. On the left the color is pure red (255, 0, 0) and on the right it is (255, 20, 5). From these you can calculate that to get full yellow, you need 255/20=13 overlapping circles and to get pure white you need 255/5=51 overlapping circles. When you reach full yellow (green channel goes to 255), there is also 65 (25%) on the blue channel, but that should not be an issue. Adjust the numbers as you feel.

Additive blending

In your case the color you should change is ocolor. If you are not rendering sprites with multiple colors, you could also use white for ocolor and draw the different colors in the texture itself. This would give more freedom to define how each pixel on the sprite behaves with additive blending.

\$\endgroup\$
5
\$\begingroup\$

Missed mentioning that my intention is for clusters of point sprites with the same pigment (red) to additive blend to yellow and white.

That right there is indicative of your problem.

You cannot take a color value of (0.25, 0, 0), and add it to itself and get anything besides more red. It will not magically become yellow, then white. It will always be red, and it will always have zero green or blue (which are necessary to achieve yellow and white).

Blending is just math; nothing more, nothing less. Math on colors is no different from math on things that aren't colors.

If you want adding "red" to eventually produce yellow and white, then you're going to need to have some blue and green in there.

Furthermore, you're going to have to use some form of tone mapping and high-dynamic range rendering to make this work out in a reasonable way.

\$\endgroup\$
1
  • \$\begingroup\$ I've found it useful to enforce a maximum saturation of 99% or so on colors in the framebuffer. This can be done quickly using rgb = max(rgb, luminance * 0.01) just before applying the tonemapping function. That way even if an artist creates something that's pure red, we'll force it to have some green and blue so it'll tonemap reasonably. \$\endgroup\$ Commented Jul 31, 2013 at 23:59
2
\$\begingroup\$

Well, your glBlendFunc(GL_ONE, GL_ONE) is likely to blame.

The 1st argument to glBlendFunc is how much of the source (new pixel) to use. The 2nd arg is how much of the destination (pixel already there in the frame buffer) to use. You said to just add 100% of the source pixel with 100% of the destination pixel. That's probably not how you want to blend for translucency though.

Common settings to get translucency are calling glBlendFunc with

glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;

An example of the math that happens is here. That says, ok, say the new pixel had alpha =0.75. Then the blended color would be 0.75*NEWPIXEL + 0.25*OLDPIXEL. Which looks like transparency.

Don't forget to turn off depth mask!.

\$\endgroup\$
3
  • \$\begingroup\$ He says he wants additive blending though. Maybe what he really wants is glBlendFunc(GL_SRC_ALPHA, GL_ONE), i.e. additive but fading out according to source alpha... \$\endgroup\$ Commented Jul 31, 2013 at 20:23
  • \$\begingroup\$ For anyone wanting to read the link to MSDN posted by bobobobo : MS has archived the blog post so the URL is wrong but the article is still there. The new address is docs.microsoft.com/en-us/archive/blogs/etayrien/… . \$\endgroup\$
    – Scylardor
    Commented Mar 23, 2020 at 22:16
  • \$\begingroup\$ Thanks @Scylardor, also here: web.archive.org/web/20150922125039/http://blogs.msdn.com/b/…, I edited your link into the post \$\endgroup\$
    – bobobobo
    Commented Mar 27, 2020 at 18:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .