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

Author Topic: [CLOSED] Add sf::BlendMode::ReverseSubtract  (Read 19964 times)

0 Members and 1 Guest are viewing this topic.

Krozark

  • Newbie
  • *
  • Posts: 36
    • View Profile
    • site perso
[CLOSED] Add sf::BlendMode::ReverseSubtract
« on: August 13, 2015, 01:49:57 pm »
Hi everyone,

I'm working on a light system with a friend, and we face a limitation of SFML, a missing BlendMode.
Currently, GL_FUNC_ADD ( alias GLEXT_GL_FUNC_ADD) and  GLEXT_GL_FUNC_SUBTRACT (alias GL_FUNC_SUBTRACT) are implemented. But what about GL_FUNC_REVERSE_SUBTRACT ?

In our specific case, it was needed to subtract light from another one (a sort of negative light).
But there is no way to do it without using a shader right now.

Am I missing a way to do this with current tool set apart from using a shader or direct OpenGL code ? If not is there any possibility of adding a ReverseSubtract to sf::BlendMode::Equation as an alias of GL_FUNC_REVERSE_SUBTRACT?

White we're at it, would it be interesting to add the GL_MIN and GL_MAX equations as well ?

If need I can take care of adding this functionality. Already made on my fork

Thanks.
« Last Edit: August 18, 2015, 09:26:36 am by Krozark »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Add sf::BlendMode::ReverseSubtract
« Reply #1 on: August 13, 2015, 02:15:02 pm »
Would it be possible to draw them in the reversed (swapped) order and use the (forwards) subtract?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Krozark

  • Newbie
  • *
  • Posts: 36
    • View Profile
    • site perso
Re: Add sf::BlendMode::ReverseSubtract
« Reply #2 on: August 13, 2015, 02:47:58 pm »
With you approach, the result will not be the one expected, expect if I'm missing something.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Add sf::BlendMode::ReverseSubtract
« Reply #3 on: August 13, 2015, 03:28:25 pm »
What is the expected result?
According to this documentation, the reverse subtraction is the source being subtracted from the destination rather than the destination being subtract from the source.
Can you not form this in an sf::BlendMode?
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

DaiMysha

  • Newbie
  • *
  • Posts: 2
    • View Profile
    • My Git Repo
Re: Add sf::BlendMode::ReverseSubtract
« Reply #4 on: August 13, 2015, 03:39:28 pm »
I'm the one who initiated the light system project.

We did some testing with a local fork of SFML and implemented the modification (which consists of 13 changed lines)

Tried it using that custom version and the result is as expected, see screenshot below.
The light emitted from the blue rectangle is white negative and cancels the lights emitted everywhere else.

If you know a way to do this without using the gl reverse subtract function reaching the result given in the screenshot i am curious because we didn't find anything that worked.

What is the expected result?
According to this documentation, the reverse subtraction is the source being subtracted from the destination rather than the destination being subtract from the source.
Can you not form this in an sf::BlendMode?

We cannot. I am rendering the lights individually on a global RenderTexture that I then draw on the window. It's not possible to invert the two textures.

The expected result is this one:

result = destination - source

That is exactly what GL_FUNC_REVERSE_SUBTRACT does
« Last Edit: August 13, 2015, 03:41:21 pm by DaiMysha »

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Add sf::BlendMode::ReverseSubtract
« Reply #5 on: August 13, 2015, 07:07:40 pm »
The light emitted from the blue rectangle is white negative
What blue rectangle?

I am rendering the lights individually on a global RenderTexture that I then draw on the window. It's not possible to invert the two textures.
Invert them? I was suggesting swapping them.

The expected result is this one:
result = destination - source
What is the destination and what is the source?

If you know a way to do this without using the gl reverse subtract function reaching the result given in the screenshot i am curious because we didn't find anything that worked.
Do what without using it? To reach the result, could do with knowing what we're using to create it. Could help if you provided the layers you are trying to blend, and in what order.


I started to guess at what you mean. Would it be:
draw a blue rectangle on something white and it would turn yellow?
If so, you could draw them in the opposite order. Draw blue rectangle first then (forwards) subtract the white.


I think you're right, though. This should (probably - any reason not to?) be added. Not sure why min and max are required.
« Last Edit: August 13, 2015, 07:40:20 pm by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

DaiMysha

  • Newbie
  • *
  • Posts: 2
    • View Profile
    • My Git Repo
Re: Add sf::BlendMode::ReverseSubtract
« Reply #6 on: August 13, 2015, 08:17:44 pm »
Apologies for the unclear answer. Let me try to explain.

What we are trying to achieve is a light that, instead of adding its component to the world, substracts them.
Say you have a purple light (red and blue), if you were to put a blue negative light on it, you would end up seeing a red light. It's what happens with the dark cone in the screenshot, since it's a pure white light, it removes every color in its path resulting in the shadow cone seen.
The underlying calcul here is (255,0,255) - (0,0,255) = (255,0,0)

My Light Manager works in (currently) 3 steps.

First step is the user drawing his world on the screen. Then the light manager draws its lights on its own texture (let's call it the light layer texture) and draws that texture on top of the users' world with a multiply.

To (hopefully) optimize the rendering, every light registered to the light manager also has its own texture in which it pre renders itself and passes onto the light manager to be draw on the light layer texture.

The light manager then adds all the lights textures into his own texture to create the light later which is then drawn on top of the user's world.
The idea of a negative light would be that instead of adding it to the light layer, it is substracted from it.

That's why it's not possible for me to invert the two texture concerned, the light manager's light layer and the lights's pre rendered texture. Inverting them would mean that i draw the light layer on top of a light's inner texture, and that cannot work.

Quote from: Hapax
What blue rectangle?
It doesn't see well because the window is dark, but at the origin of the dark cone, in the screenshot, there is a blue square representing the player's position.

Quote from: Hapax
What is the destination and what is the source?
In this case, the result is what you see on the screen (the black cone, after multiplying it to the user's world),
the destination is the light manager's light layer texture and the source is the light's pre-rendered texture

If we suppose layers are added from left to right, what i'm trying to achieve here is :
[users's world] * [light manager base color + lights - negative lights]

The issue here being the - negative lights part. We could have it by using a shader or pure OpenGL code but we simply don't understand why this option hasn't been made available right from the start.

Quote from: Hapax
Not sure why min and max are required.
I don't know why they would be, but i don't see a reason not to include them. They've been made available by OpenGL so why not ? And if one day someone actually finds a use to them, he'll be happy that they are available and don't find themseves in my position.

Hopefully this answer is clearer regarding our intentions and issue.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Add sf::BlendMode::ReverseSubtract
« Reply #7 on: August 13, 2015, 08:24:33 pm »
What we are trying to achieve is a light that, instead of adding its component to the world, substracts them.
sf::BlendMode reverseSubtract(sf::BlendMode::Zero, sf::BlendMode::OneMinusSrcColor, sf::BlendMode::Equation::Add);
8)

I don't know why they would be, but i don't see a reason not to include them. They've been made available by OpenGL so why not ? And if one day someone actually finds a use to them, he'll be happy that they are available and don't find themseves in my position.
From previous discussions on this forum that I've seen, this seems to me to be a certain reason for rejection. Including stuff because you can in hope that someone might want it someday does not seem to be the philosophy behind SFML, which makes sense.

EDIT: altered variable's name in the code for clarification
« Last Edit: August 13, 2015, 08:30:30 pm by Hapax »
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Krozark

  • Newbie
  • *
  • Posts: 36
    • View Profile
    • site perso
Re: Add sf::BlendMode::ReverseSubtract
« Reply #8 on: August 14, 2015, 10:00:33 am »
From previous discussions on this forum that I've seen, this seems to me to be a certain reason for rejection. Including stuff because you can in hope that someone might want it someday does not seem to be the philosophy behind SFML, which makes sense.

Here, we don't ask this feature for Fun but because : it is available on OpenGL, and SFML doesn't allow us to use theme. Why?
OpenGL allows 5 blend mode (GL_FUNC_ADD, GL_FUNC_SUBTRACT, GL_FUNC_REVERSE_SUBTRACT, GL_MIN and GL_MAX), but only two of theme are available (GL_FUNC_ADD, GL_FUNC_SUBTRACT).

The request is : Make the five available on SFML. This is as simple as that.
Here is a link to the commit on the fork to show you the changes : https://github.com/Krozark/SFML/commit/0a84d785c5de6fe34f90e41ba65fd2e1218ad209

Now, concerning the project, we tried a lot a combinations of sf::BlendMode before posting here, including your proposal (which gives a good approximation but not exactly the result we wanted).  None of theme works as expected using sf::BlendMode::Equation::Add or sf::BlendMode::Equation::Substract. For our case we NEED (yes, in big) GL_FUNC_REVERSE_SUBTRACT.
Concerning Min and Max, we don't need them at all, but I already explained my opinion on this at the beginning of this post.

We did additional tests to show that the result we get with your solution isn't exactly what we wanted. See the results in the attached screenshots.

We picked three spots with a (50,0,50) light, giving a center spot of a (150,0,150) color.
We used a negative color of (0,0,50) in the center of it. We expect a center resulting value of (150,0,100), which we obtain with the ReverseSubtract, while your solution gives us a color of (150,0,121). While being a good approximation, it isn't exactly what we need and a difference of 21% (here) is too high to be accepted because visible to the naked eye.
« Last Edit: August 14, 2015, 10:12:33 am by Krozark »

Laurent

  • Administrator
  • Hero Member
  • *****
  • Posts: 32498
    • View Profile
    • SFML's website
    • Email
Re: Add sf::BlendMode::ReverseSubtract
« Reply #9 on: August 14, 2015, 10:36:22 am »
If GL_FUNC_REVERSE_SUBTRACT exists, I guess you can trust OpenGL that this is because it can't be emulated with other modes. So indeed, you'll probbaly never have the exact same result with any other combination of blend modes.

So, adding it to SFML is an option. However I still don't understand what these "negative" lights mean; what effects do you achieve with them? Could it be that this concept of "negative light" is a wrong solution to a more fundamental problem (lighting algorithm)?

Regarding the other OpenGL blend modes, there is an obvious reason to not add them "just because they exist": SFML is a simple library, not a 1:1 wrapper on top of OpenGL. OpenGL is at the lowest level of graphics abstraction, its API is (and has to be) a direct mapping of what the graphics card can do, because there's no other way to access these features otherwise. SFML is at a higher-level, it tries to extract a meaningful set of features from all this clutter. However, simple doesn't mean limited, and if one day GL_MIN and GL_MAX prove to be useful, then they'll be considered more seriously.

Note that this is my personal opinion, others (including team members) may disagree.
Laurent Gomila - SFML developer

Mario

  • SFML Team
  • Hero Member
  • *****
  • Posts: 879
    • View Profile
Re: Add sf::BlendMode::ReverseSubtract
« Reply #10 on: August 14, 2015, 11:11:53 am »
@Laurend I'd actually consider Min/Max to be more important than Reverse Substract. :)

Krozark

  • Newbie
  • *
  • Posts: 36
    • View Profile
    • site perso
Re: Add sf::BlendMode::ReverseSubtract
« Reply #11 on: August 14, 2015, 11:17:14 am »
However I still don't understand what these "negative" lights mean; what effects do you achieve with them?

In reality negative light don't exist at all, but let take the case of a RPG. Imagine that your hero can throw spell of darkness, witch remove a color.
This is the idea of negative light.

Example :
Ambient color = (127,50,203)
Darkness spell  = (0,12,150)

final scene color = Ambient color  - Darkness spell
                = (127, 38, 53)

Could it be that this concept of "negative light" is a wrong solution to a more fundamental problem (lighting algorithm)?

I don't think so. It' more a new concept (which is be a bit confusing, I agree).


Regarding the other OpenGL blend modes, there is an obvious reason to not add them "just because they exist": SFML is a simple library, not a 1:1 wrapper on top of OpenGL.

I understand It. This is why, through this thread, we try to convince you (and other SFML team member) the need of it through concert example.

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Add sf::BlendMode::ReverseSubtract
« Reply #12 on: August 14, 2015, 01:06:35 pm »
Negative lights are actually a rather commonly used concept. Sometimes it's simpler to "add darkness" than to adjust all lights to make that area darker. Maybe not that common in 2D gaming but still...

your proposal...which gives a good approximation but not exactly the result we wanted
It's true that it wasn't perfect as it's based on multiplication rather than linear subtraction. I find it ironic, though, that you found it unacceptable as multiplication is more commonly done via multiplication, and I'm not sure why you need exact numbers. Since it's lighting, the negative light's 'power' could be 'turned up' to accommodate.
Saying that, it was only a suggestion.

it is available on OpenGL, and SFML doesn't allow us to use theme. Why?
SFML's graphics module doesn't provide abstract access to everything that OpenGL does but SFML itself does allow access to OpenGL, if you're willing to use OpenGL.

Again, I still agree that it should be included; it's just sometimes your reasoning isn't best put  ;)

I'd actually consider Min/Max to be more important than Reverse Substract. :)
Why?
Its not that I disagree; I just wonder what they'd be so commonly used for.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

shadowmouse

  • Sr. Member
  • ****
  • Posts: 302
    • View Profile
Re: Add sf::BlendMode::ReverseSubtract
« Reply #13 on: August 14, 2015, 01:14:09 pm »
I agree this is a good idea. The SFML interface is easier to use than OpenGL, because it is simpler, but I don't think that purposefully excluding functionality in this way makes it easier to use. Correct me if I'm wrong, but this just extending an enum (from the user's point of view) and that doesn't make SFML harder to use, especially if in tutorials you were to say "These are the basic blend modes, then you have these for specific circumstances". Also on the topic of negative light, I think that being able to create, for example, black plasma blast style effects, or even just a black fire/lantern is not only cool graphically but can add to games. Should not the ideal library give you as much control as possible, in the easiest way possible. Personally, I've never had to use blend modes (because SFML does it for me by default), hence it is simple, but being a powerful library means it should give you control when you need it.

Krozark

  • Newbie
  • *
  • Posts: 36
    • View Profile
    • site perso
Re: Add sf::BlendMode::ReverseSubtract
« Reply #14 on: August 14, 2015, 01:36:13 pm »
Correct me if I'm wrong, but this just extending an enum (from the user's point of view) and that doesn't make SFML harder to use

Exactly, and a switch on this enum  values to complete (from a SFML developer point of view).

 

anything