[SOLVED] How not to get additive alpha

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
Bigfoot71
Party member
Posts: 287
Joined: Fri Mar 11, 2022 11:07 am

[SOLVED] How not to get additive alpha

Post by Bigfoot71 »

Hello everyone !

I would like to know how not to have the alpha values ​​that add up, here is an image of what I would like.

First the default situation, and second what I would like:
ImageImage

So I tried several ways but I can't find a way without having to use a canvas (i.e. draw in a canvas then apply the alpha to the canvas display).
I for example use blendmodes but it's never what I expect, for example with lg.setBlendMode("replace") I got this:
Image

We can see that the alpha has not been added but there is no more transparency, so maybe I'm doing it wrong.

Here is my code for the last example image:

Code: Select all

local win_w, win_h = love.graphics.getDimensions()

local x1, y = win_w/2, win_h/2
local x2, x3 = x1-100, x1+100

function love.draw()

    love.graphics.setColor(.5,.5,.5,1)
    love.graphics.rectangle("fill", 0,0,x1,win_h)

love.graphics.setBlendMode("replace")

    love.graphics.setColor(1,1,0, .5)
    love.graphics.circle("fill", x1, y, 100)
    love.graphics.circle("fill", x2, y, 100)
    love.graphics.circle("fill", x3, y, 100)

love.graphics.setBlendMode("alpha")

end
Last edited by Bigfoot71 on Wed Nov 16, 2022 4:13 pm, edited 1 time in total.
My avatar code for the curious :D V1, V2, V3.
User avatar
BrotSagtMist
Party member
Posts: 607
Joined: Fri Aug 06, 2021 10:30 pm

Re: How not to get additive alpha

Post by BrotSagtMist »

Youre trying to mix two different blending types, that cant work.
Canvas is the _sane_ solution here, is there a reason you want to avoid them?

FYI: A possible way is to turn all circles into one polygon, the overhead of creating such polygon isnt worth the effort tho.
obey
User avatar
darkfrei
Party member
Posts: 1169
Joined: Sat Feb 08, 2020 11:09 pm

Re: How not to get additive alpha

Post by darkfrei »

Reminds me a shadows merging problem (and solution):
Kovarex wrote:Shadows merging
One of the problems I had when implementing the gates was, that when the shadows overlap, they make ugly "double shadow" areas. This is best visible on the picture of the tank. The turret needs to be drawn separately, as it can rotate independently, the resulting shadow shows the overlap of those two objects.
Image
So I had to make a method, where the shadows of some objects can be drawn separately into one picture as 100% black shapes. Once the shadows are merged in the picture, they are drawn on the screen with 50% transparency and tadaaaa ... all the overlaps are gone.
Read here:
https://www.factorio.com/blog/post/fff-56
:awesome: in Lua we Löve
:awesome: Platformer Guide
:awesome: freebies
User avatar
Bigfoot71
Party member
Posts: 287
Joined: Fri Mar 11, 2022 11:07 am

Re: How not to get additive alpha

Post by Bigfoot71 »

BrotSagtMist wrote: Wed Nov 16, 2022 12:39 am is there a reason you want to avoid them?
The three reasons are:
  • The fact that it existed may be a simpler and less expensive solution.
  • The fact that if two colors are superimposed in the canvas, once the transparency is applied we will only see the color on top, so I would like the colors to add up but not the transparency (sorry for not having it good enough precise).
  • And lastly, because I use a camera system (which doesn't make it any easier even if it's far from being insurmountable) and it also requires me to change a lot of other things in the way of display the objects in my scene, this last point remains a bit of a question of laziness on my part ^^
darkfrei wrote: Wed Nov 16, 2022 8:09 am Reminds me a shadows merging problem (and solution)
Is it basically the same principle as displaying in a canvas at 100% opacity and then applying transparency?
Or would Love2d have a way to generate textures as efficiently as pure SDL? (if i'm not too confused)

In any case, we come back to the problem of my second point that I have just stated, unless there is a solution.

Edit:

lg.setBlendMode("add", "premultiplied") seemed to give the correct result but no matter the given alpha value the result is the same, so I have a doubt about. (if "alpha == 1" still a transparency). After several checks it looks like but is not what I described.
My avatar code for the curious :D V1, V2, V3.
User avatar
BrotSagtMist
Party member
Posts: 607
Joined: Fri Aug 06, 2021 10:30 pm

Re: How not to get additive alpha

Post by BrotSagtMist »

Thing is once you applied a circle to the screen it is not possible for the next circle to distinguish between the ground texture and the last circle, it will therefore have no other choice but to alter these pixels.
Well you could use the last draw as a stencil but that is basically canvas wit extra steps.
obey
User avatar
slime
Solid Snayke
Posts: 3131
Joined: Mon Aug 23, 2010 6:45 am
Location: Nova Scotia, Canada
Contact:

Re: How not to get additive alpha

Post by slime »

It should work to use the 'lighten' blend mode while drawing the shapes to a canvas, and then use (premultiplied) alpha blending when drawing/compositing the canvas to the screen.

The lighten blend mode doesn't support non premultiplied alpha, so you might have to multiply rgb with alpha in a shader when doing that.
User avatar
Bigfoot71
Party member
Posts: 287
Joined: Fri Mar 11, 2022 11:07 am

Re: How not to get additive alpha

Post by Bigfoot71 »

slime wrote: Wed Nov 16, 2022 2:00 pm It should work to use the 'lighten' blend mode while drawing the shapes to a canvas, and then use (premultiplied) alpha blending when drawing/compositing the canvas to the screen.
Thanks a lot ! I just got exactly the result I was looking for with the 'lighten' mode without canvas or shader !

There is just the default opacity on black, but in my case it's not a problem.
In case it bothers, applying the complete solution (of Slime) would be useful.

Demonstration

With a single color, we see that the transparency does not add up and that the background is visible:
Image

And with several colors, they "add" together, except the alpha and we always see the background:
Image

And to say that I was going for another type of rendering for the colors using the 'darken' mode while the solution was just above in the wiki :death:

Thank you very much again ! :D


The code of the last image to reproduce the effect:

Code: Select all

local win_w, win_h = love.graphics.getDimensions()

local x1, y = win_w/2, win_h/2
local x2, x3 = x1-100, x1+100

function love.draw()

    love.graphics.setBlendMode("alpha", "premultiplied")

    love.graphics.setColor(.5,.5,.5, 1)
    love.graphics.rectangle("fill", 0,0,x1,win_h)

    love.graphics.setBlendMode("lighten", "premultiplied")

    love.graphics.setColor(0,1,0, .5)
    love.graphics.circle("fill", x1, y, 100)

    love.graphics.setColor(1,0,0, .5)
    love.graphics.circle("fill", x2, y, 100)

    love.graphics.setColor(0,0,1, .5)
    love.graphics.circle("fill", x3, y, 100)

end
My avatar code for the curious :D V1, V2, V3.
Post Reply

Who is online

Users browsing this forum: No registered users and 55 guests