Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: Unexpected alpha-blending result with render texture  (Read 4243 times)

0 Members and 1 Guest are viewing this topic.

Haze

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Github Profile
Unexpected alpha-blending result with render texture
« on: April 17, 2019, 06:48:21 pm »
Hi,

I want to draw a white square with half-opacity (alpha 128), but the alpha-blending isn't rendered as expected when I draw on a render texture.

Why don't the two following methods render the same result?

Method A:
    1. Draw something on a render texture
    2. Draw the render texture on render window
    3. Draw a white square with half-opacity on render window

Method B:
    1. Draw something on a render texture
    2. Draw a white square with half opacity on the render texture
    3. Draw the render texture on render window

#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(320, 240), "sfml", sf::Style::Close);

    sf::RectangleShape black({20 ,240});
    black.setPosition(100, 0);
    black.setFillColor(sf::Color::Black);

    sf::RectangleShape white({60, 60});
    white.setPosition(80, 50);
    white.setFillColor(sf::Color(255, 255, 255, 128));

    sf::RenderTexture texture;
    texture.create(window.getSize().x, window.getSize().y);
    sf::Sprite sprite(texture.getTexture());

    // Method A: Draw white square on render texture
    texture.clear(sf::Color::Transparent);
    texture.draw(black);
    texture.draw(white);
    texture.display();

    white.setPosition(80, 160);
    while (window.isOpen()) {
        sf::Event event;
        while (window.pollEvent(event)) {
            if (event.type == sf::Event::Closed) {
                window.close();
            }
        }
        // Method B: Draw white square on render window
        window.clear(sf::Color::Blue);
        window.draw(sprite);
        window.draw(white);
        window.display();
    }
    return 0;
}
 

Image result in attachement.


Am I missing something?

- OS: Debian 9
- GPU: Mesa DRI Intel(R) Haswell Mobile (0xa16)
- SFML Version: 2.5.1

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Unexpected alpha-blending result with render texture
« Reply #1 on: April 17, 2019, 07:41:22 pm »
Look at the blending mode that you're using, check its detailed definition, apply the formulas and you'll figure out what happens. Focus on what alpha value is written to the RenderTexture for your white square.
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Unexpected alpha-blending result with render texture
« Reply #2 on: April 17, 2019, 08:07:23 pm »
You apply the blending twice. Once when you render it to the render texture and once when you render it to the window.
For the RT you probably want blend mode 'None'.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Unexpected alpha-blending result with render texture
« Reply #3 on: April 17, 2019, 08:34:19 pm »
Quote
For the RT you probably want blend mode 'None'.
No because he needs alpha blending on top of the black rectangle. He probably needs to apply regular alpha blending to color channels, and keep a fully opaque alpha channel on the RT (-> custom blending).
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Unexpected alpha-blending result with render texture
« Reply #4 on: April 18, 2019, 12:00:22 am »
Ah right, but at least it explains the reason why it's rendered differently.
So yes, the solution is a custom blend formula.

Also quite some optical illusion where you think the grey in the middle is of a different shade, while it actually is the same grey. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Haze

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Github Profile
Re: Unexpected alpha-blending result with render texture
« Reply #5 on: April 18, 2019, 06:57:26 pm »
Hey,

Quote
You apply the blending twice. Once when you render it to the render texture and once when you render it to the window.
How comes the blending is applied twice? The shape white that I labeled "weird blending" is only drawn once!

If I'm not mistaken, when I draw the shape white drawn on the RT, the result is stored inside the RT.

So, I'd expect drawing this RT to a render window would behave the same as drawing a PNG with transparency.

Quote
keep a fully opaque alpha channel on the RT (-> custom blending).
This alone makes a difference. If I clear the RT with an opaque color (instead of sf::Color::Transparent), I got the expected result (the two squares look the same).

But I think I have a better understanding of my issue now: I saved the RT to png file. (see attachement).

We can see that rendering rgba(255, 255, 255, 128) on sf::Color::Transparent results in rgba(128, 128, 128, 128), because sf::Color::Transparent is defined as "black" rgba(0, 0, 0, 0).

Whereas I was expecting the result to be rgba(255, 255, 255, 128).

So, is this behavior of sf::BlendAlpha + sf::Color::Transparent intended?

Thanks,
« Last Edit: April 18, 2019, 06:58:59 pm by Haze »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Unexpected alpha-blending result with render texture
« Reply #6 on: April 18, 2019, 09:13:41 pm »
Yes, because that's how sf::BlendAlpha is defined. You don't need to guess stuff, the formula is written right there, just have a look, don't be afraid ;)

And yes, sf::Color::Transparent is nothing special, you can use white transparent instead of black transparent if it better suits your needs.
Laurent Gomila - SFML developer

Haze

  • Full Member
  • ***
  • Posts: 201
    • View Profile
    • Github Profile
Re: Unexpected alpha-blending result with render texture
« Reply #7 on: April 20, 2019, 08:53:13 am »
Quote
you can use white transparent instead of black transparent if it better suits your needs

This is a very handy solution for my use case, thank you.

Just curious, is there any reason for sf::Color::Transparent being defined as black transparent (instead of white transparent?).

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Unexpected alpha-blending result with render texture
« Reply #8 on: April 20, 2019, 09:30:55 am »
Nop, there's nothing special about transparent being black.
Laurent Gomila - SFML developer