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

Author Topic: Fading without artifacts  (Read 17987 times)

0 Members and 1 Guest are viewing this topic.

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: Fading without artifacts
« Reply #15 on: October 01, 2012, 12:59:53 pm »
Can you explain more clearly why not clearing a rendertexture is bad? To my understanding clear() only paints the whole render target in a single color.
I thought about storing all the element individually, but is not an option for my program, because it's only a small program, but it has quiet a lot of elements, so it would use unreasonably huge amounts of memory. And that's not very efficient.

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: Fading without artifacts
« Reply #16 on: October 01, 2012, 05:08:14 pm »
I might be wrong, but the RenderTexture, like the window needs to be cleared so that nothing unexpected appears in it. Display function displays anything that has been drawn beforehand, but doesn't clear it from previous pixels. You need to clear so that the window/rendertexture draws from scratch and it helps avoid unexpected behaviour.

For example try a simple code of moving a sprite without clearing the window, instead of the clean sprite moving what you will have is the sprite image displaying itself as it moves, so it doesn't show movement, rather it displays the sprite at many different positions that it has taken overtime.
« Last Edit: October 01, 2012, 05:12:00 pm by masskiller »
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Fading without artifacts
« Reply #17 on: October 01, 2012, 05:37:21 pm »
For example try a simple code of moving a sprite without clearing the window, instead of the clean sprite moving what you will have is the sprite image displaying itself as it moves, so it doesn't show movement, rather it displays the sprite at many different positions that it has taken overtime.
That's the effect he's trying to get. ;)

Can you explain more clearly why not clearing a rendertexture is bad? To my understanding clear() only paints the whole render target in a single color.
I'm not sure about this. It could very well be that it's okay for render texture but not for the window...

I thought about storing all the element individually, but is not an option for my program, because it's only a small program, but it has quiet a lot of elements, so it would use unreasonably huge amounts of memory. And that's not very efficient.
What numbers are we talking about here?
I'd say you would need to care for the memory usage it's not as much as a problem as the storing/erasing/drawing itself.
I've seen your application but I don't know how you did it, so I can't help you further on how to optimize.

I'm not sure how SFML handles the blending but from my understanding this shouldn't be the expected behavior. It should keep going dimmer and dimmer until the decimal points get rounded to 0.
But instead the darkness depends on the alpha channel you're using.
For instance, if you set the color to (0, 0, 0, 1) the result will look like:


But if you use (0, 0, 0, 10) you'll get:


Testing code:
#include <SFML/Graphics.hpp>

int main()
{
    sf::RenderWindow window(sf::VideoMode(1024, 768), "SFML");
    window.setFramerateLimit(60);

    sf::RenderTexture m_RenderTexture;
    m_RenderTexture.create(window.getSize().x, window.getSize().y);
    sf::Sprite m_RenderSprite;

    sf::RectangleShape FadeRect(sf::Vector2f(window.getSize()));
    FadeRect.setFillColor(sf::Color(0, 0, 0, 1));

    sf::CircleShape circle;
    circle.setRadius(10);
    circle.setFillColor(sf::Color::Red);

    m_RenderSprite.setTexture(m_RenderTexture.getTexture());

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed)
                window.close();
        }

        circle.setPosition(sf::Vector2f(sf::Mouse::getPosition(window)));
        m_RenderTexture.draw(circle);
        m_RenderTexture.draw(FadeRect);
        m_RenderTexture.display();

        window.clear();
        window.draw(m_RenderSprite);
        window.display();
    }
}
« Last Edit: October 01, 2012, 05:39:15 pm by eXpl0it3r »
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

masskiller

  • Sr. Member
  • ****
  • Posts: 284
  • Pointers to Functions rock!
    • MSN Messenger - kyogre_jb@hotmail.com
    • View Profile
    • Email
Re: Fading without artifacts
« Reply #18 on: October 01, 2012, 05:52:43 pm »
Quote
That's the effect he's trying to get. ;)

Sorry then. It's been long since I read the topic and as I am in my University I didn't even try to make a sample code since I would have to set a project just to do it. My bad.
Programmer, Artist, Composer and Storyline/Script Writer of "Origin of Magic". If all goes well this could turn into a commercial project!

Finally back into the programming world!

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Fading without artifacts
« Reply #19 on: October 01, 2012, 05:59:33 pm »
So after further testing this really seems like a bug, probably some float vs integer stuff.

If you use a black rect with alpha = 1 the final color of the originally red circle will be (128, 0, 0) thus exactly half of the original color. If you now set the original color to (128, 0, 0) and the fading alpha channel to 1, the color doesn't even change, it just stays (128, 0, 0).

Then again if you use alpha = 128 the resulting color will be 100% black, but alpha = 127 will get you a (1, 0, 0) color.

Like I already said what should actually happen is that the color should get dimmer and dimmer until it gets rounded completely to black and not some more or less random red-ish. ;)
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: Fading without artifacts
« Reply #20 on: October 01, 2012, 06:09:45 pm »
Quote
probably some float vs integer stuff
Most likely.
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Fading without artifacts
« Reply #21 on: October 01, 2012, 07:50:07 pm »
Quote
probably some float vs integer stuff
Most likely.
And that now means what exactly? ???
Will you investigate it/fix it? ???
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: Fading without artifacts
« Reply #22 on: October 01, 2012, 08:59:05 pm »
If it's not a bug, then there's nothing to investigate and fix. If it's the expected behaviour according to what happens on the graphics card, then you should rather find another technique.
Laurent Gomila - SFML developer

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Fading without artifacts
« Reply #23 on: October 01, 2012, 09:25:57 pm »
If it's not a bug, then there's nothing to investigate and fix. If it's the expected behaviour according to what happens on the graphics card, then you should rather find another technique.
Sorry I'm still confused... Why are you using if-sentences? :-\

For me it seems like a bug and not the expected behavior, but I didn't create SFML and I don't have any knowledge on OpenGL, so I'm asking you: Is it a bug or is it the expected behavior?

From a logical point of view it's obvious that at some point it should turn completely black and not get stuck a certain point. One can also try this with an image editor, if you add more and more semi transparent objects on top of each other the color will at some point get solid.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: Fading without artifacts
« Reply #24 on: October 01, 2012, 09:36:10 pm »
Yeah I feel like it's not the expected behaviour. I think it might be a float / integer conversion too. Maybe it's because the sf::Color components are defined as Uint8. Maybe using floats will solve the issue.

Part of my original question was how to achieve the desired effect with another technique. Would it be possible to maybe use a shader?

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Fading without artifacts
« Reply #25 on: October 01, 2012, 11:08:37 pm »
Quote
Sorry I'm still confused... Why are you using if-sentences?
I can't be 100% sure, I'm not inside the graphics card to see what happens there ;)

Quote
I'm asking you: Is it a bug or is it the expected behavior?
I don't think it's a bug, but it's not what one would expect either. However, if you think about the operations involved (working with 8-bit color components), it seems to be "normal".

Quote
Maybe using floats will solve the issue.
Using floats everywhere would be very complicated (using them in sf::Color wouldn't be enough).

Quote
Part of my original question was how to achieve the desired effect with another technique. Would it be possible to maybe use a shader?
Storing all the points and decrementing their alpha slowly is the best solution. How many points do you want to draw? If they fade out, you should never hav a huge list of points to draw.
Laurent Gomila - SFML developer

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: Fading without artifacts
« Reply #26 on: October 01, 2012, 11:16:53 pm »
Quote
I can't be 100% sure, I'm not inside the graphics card to see what happens there ;)
No?  :(

Quote
I don't think it's a bug, but it's not what one would expect either. However, if you think about the operations involved (working with 8-bit color components), it seems to be "normal".
Isn't something unexpected or unintended happening the definition of a bug?  ;)
Going by that logic, doing something really stupid that crashes the program or introduces ub is not a bug because 'if you think about the operations involved (reinterpret casts, deleting stack variables, overflowing the buffers ect.), it seems to be "normal" ' ;)

Quote
Storing all the points and decrementing their alpha slowly is the best solution. How many points do you want to draw? If they fade out, you should never hav a huge list of points to draw.
Chances are they all fade out at same rate so some fifo list would speed it up, deque maybe.

btw: Does the above code snippet work without adding clear() call after creation? On my laptop rendertexture starts with complete garbage, last program's rendertexture contents ect. if I don't do call clear.
But if I do it's alright.(yes, laptop with intel's grapics ::)).
Back to C++ gamedev with SFML in May 2023

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11030
    • View Profile
    • development blog
    • Email
Re: Fading without artifacts
« Reply #27 on: October 01, 2012, 11:25:24 pm »
Isn't something unexpected or unintended happening the definition of a bug?  ;)
Going by that logic, doing something really stupid that crashes the program or introduces ub is not a bug because 'if you think about the operations involved (reinterpret casts, deleting stack variables, overflowing the buffers ect.), it seems to be "normal" ' ;)
It doesn't crash and doesn't create any problems, it just doesn't fully do what one would dream of. Also it doesn't really seem to be related to SFML itself.
To some extend it makes sense in a way that if the layer is < 128 there'll always be some bits getting shown and with >= 128 everything gets wiped out. Now you could try to get things to fade slowly be attaching the drawing of the fader to a sf::Clock and time it differently than just drawing it every frame.

Chances are they all fade out at same rate so some fifo list would speed it up, deque maybe.
Something like that, only problem is you'll have to be able to iterate over it. ;)

btw: Does the above code snippet work without adding clear() call after creation? On my laptop rendertexture starts with complete garbage, last program's rendertexture contents ect. if I don't do call clear.
But if I do it's alright.(yes, laptop with intel's grapics ::)).
Well some compilers/computers/whatever clear such buffers and then it seems to work, but that's not something you can rely on. I simply forgot to add it, although I initially had it in mind. ;)
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: Fading without artifacts
« Reply #28 on: October 01, 2012, 11:46:50 pm »
Quote
Isn't something unexpected or unintended happening the definition of a bug?
There's a big difference. A bug is a programming mistake that makes the program not behave as specified. This is clearly not the case, (it seems that) the graphics card behaves exactly as it is supposed to, it's just not very intuitive for the end user in this specific context.
Laurent Gomila - SFML developer

Foaly

  • Sr. Member
  • ****
  • Posts: 453
    • View Profile
Re: Fading without artifacts
« Reply #29 on: October 03, 2012, 01:39:53 am »
So you're saying that is not a bug? Does that mean I shouldn't expect this issue to be resolved? I would really like see this beeing improved. I think I would be more intuitive and more like user would expect it to behave. Or could the subtractive blend mode be added as an alternative and kind of a workaround for problems like this?

Keeping count of all my objects is not an option, because it would be way to much memory usage for something that can be solved with the way more efficient rendertexture. So would another idea work: I simply draw a transparent rectangle (sf::blendmode::none) over the whole scene on the rendertexture and apply a shader to it. The shader does a texture lookup from the rendertexture. Then you take that color and subtract some of the alpha. Would that work? Or is there another way to apply a global shader to a rendertexture?