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

Author Topic: How to use blend modes to invert colors on overlap?  (Read 3466 times)

0 Members and 3 Guests are viewing this topic.

AllergicGorilla

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
How to use blend modes to invert colors on overlap?
« on: December 18, 2017, 05:01:01 pm »
In my game, I have a line class that is drawn on top of circles.The thing is, those circles have the same color as the line when highlighted, so it gets pretty difficult to distinguish them(impossible when the line is too small)https://i.imgur.com/RZJviGv.png.I could just change the color of the line, but I think a blend mode(like https://i.stack.imgur.com/LuWAA.png) would be the most future-proof way to visualize this line, as it overlaps other entities.

I've already read up on the docs https://www.sfml-dev.org/documentation/2.4.2/structsf_1_1BlendMode.php but I'm still pretty much confused as to how I implement this specific blend mode.Actually, I think I still don't understand sf::BlendMode at all.This was my attempt:

    // Draw charges
    for (auto s : chargeVector) {
        mainWindow.draw(*s);
        if (s->getIsCursorOn()) {
            // Draw charge
            mainWindow.draw(*s, &chargeHighlightShader);
            // Draw velocity line
            mainWindow.draw(
                s->velocityLine(),
                sf::BlendMode(sf::BlendMode::Zero,
                              sf::BlendMode::OneMinusDstColor,
                              sf::BlendMode::Add));
        } else
            mainWindow.draw(*s);
    }

It's best if I give my current "understanding" of this code snippet, just so that you can clarify my misconceptions and better pinpoint the problem(s):

sf::BlendMode is just a part of the renderstate of the drawable object(in this case, a "Line") which is passed as an argument to it's draw() method.

The constructor I'm using takes three arguments:

  • sourceFactor:In this case, it means how much a pixel of the line(src) affects the final output.This is set to zero, that is, the color and alpha of each pixel of the line is just being ignored.
  • destinationFactor:In this case, it means how much a pixel of the current buffer(dst) affects the final output.This is set to vec4(1.0) - pixel.rgba, that is, it's colors are completely inverted, including the alpha.
  • blendEquation:Determines how the src and dst values should be mixed.Set to add(pretty self-explanatory).

I guess the only problem I see is in the second argument, for which the alpha value is set to 1.0 - 1.0 = 0.0.But if that's the problem, how do I fix it?

Oh and this is what happens when I use my attempt:https://i.imgur.com/RkSmcHS.png

NGM88

  • Full Member
  • ***
  • Posts: 162
    • View Profile
Re: How to use blend modes to invert colors on overlap?
« Reply #1 on: December 18, 2017, 08:54:46 pm »
So your line is red and you want it to be a different color when it's drawn over a red circle.

This can help if you'll consider using a shader instead of sfml blend modes:

https://app.box.com/s/hijgkl6tt9

It's GLSL code to emulate photoshop blending modes. Exclusion and Difference modes can do what you want. They would make the line red over black and black over red. But then it would also make the line cyan if you draw over white circles  :P

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: How to use blend modes to invert colors on overlap?
« Reply #2 on: December 18, 2017, 09:02:35 pm »
Can you describe in more details or with a picture what exactly you want to do? Is maybe sf::BlendMode mode(sf::BlendMode::OneMinusDstColor, sf::BlendMode::Zero, sf::BlendMode::Add) what you're looking for?
Back to C++ gamedev with SFML in May 2023

AllergicGorilla

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: How to use blend modes to invert colors on overlap?
« Reply #3 on: December 19, 2017, 06:26:48 pm »
Can you describe in more details or with a picture what exactly you want to do? Is maybe sf::BlendMode mode(sf::BlendMode::OneMinusDstColor, sf::BlendMode::Zero, sf::BlendMode::Add) what you're looking for?


Yes! that's what I was looking for! thanks  :)
https://i.imgur.com/g79Hjzi.png

There's just one thing: the color doesn't seem to be negative(see the image--the important line is the one that originates in the center of the red circle)

Still, it makes the line pretty distinguishable!

Could you please explain what I was doing wrong? It seems the only thing that was changed was the order of the first two arguments...

Just to clarify: I wanted the line's color to be opposite of that of the background's(everything that was drawn before it) so that the line was always visible.

So your line is red and you want it to be a different color when it's drawn over a red circle.

This can help if you'll consider using a shader instead of sfml blend modes:

https://app.box.com/s/hijgkl6tt9

It's GLSL code to emulate photoshop blending modes. Exclusion and Difference modes can do what you want. They would make the line red over black and black over red. But then it would also make the line cyan if you draw over white circles  :P

Oh that's interesting! I've tried using shaders but I'm pretty much a noob.

I thought it was impossible to make a shader for blending in SFML. Wouldn't I need access to the previous buffer(background) to blend with the current one(line)?

FRex

  • Hero Member
  • *****
  • Posts: 1848
  • Back to C++ gamedev with SFML in May 2023
    • View Profile
    • Email
Re: How to use blend modes to invert colors on overlap?
« Reply #4 on: December 19, 2017, 09:49:34 pm »
I tried to make it fit the formula so that:
dst.rgb = colorSrcFactor * src.rgb (colorEquation) colorDstFactor * dst.rgb
turned into:
dst.rgb = (1 - dst.rgb) * src.rgb

Did you try it with a white line? That would give you the inversion of color like in paint or so. If not then I'm still not getting what effect you're trying to achieve.
« Last Edit: December 19, 2017, 09:51:34 pm by FRex »
Back to C++ gamedev with SFML in May 2023

AllergicGorilla

  • Newbie
  • *
  • Posts: 6
    • View Profile
    • Email
Re: How to use blend modes to invert colors on overlap?
« Reply #5 on: December 20, 2017, 01:47:29 am »
Problem solved! Thanks :D

I forgot that the red color would interfere with the blending.Now I've put a white color as default and it works as expected.https://i.imgur.com/80u2Ncl.png(In case you can't see, the line is cyan when inside the red circle)