Page 1 of 1

Changing part of image transparency?

Posted: Wed Jul 12, 2017 9:32 am
by Yaaghër
Hello, I hope my question isn't too stupid but I'm relativly new in löve, so I don't know if it's completely impossible and stupid to ask or not.
And escuse my english, sorry.

Here's the thing: Until now I 'played' with löve to learn few things and I now aim to make ' game', little rogue-like with procedural dungeon and enemies, I now have most of the knowledge I need to do most of it, or at least using the libraries you so kindly share.

Now the problem is toward the graphical side; I don't want to overload löve by asking it to draw every single objects and walls separatly, I know most of my code is badly done so performance wise it will be a mess (as I aim to add plenty of ennemies and objects). I was planning to draw the floor and the things the player wouldn't be under in one image, and another image with eveything the player could be 'under' (walls, doors, tables, lamps, etc...).

This is if this can be done:
Is it possible to change only part of an image's transparency? By that I mean to change the opacity of only some pixels of an image to make them more or less transparent without changing the whole image's alpha. For example, to change only the image's alpha between x to x+something and y to y+something where the player is under the image and between these coordinates, without changing the player transparency.

Thanks

Re: Changing part of image transparency?

Posted: Wed Jul 12, 2017 2:02 pm
by erasio
The answer is a stencil!
https://love2d.org/wiki/love.graphics.stencil

Basically it allows you to define a mask. Telling love.graphics: "There pixels are special!"

Afterwards you can use setStencilTest to tell your scene "Don't draw pixels here!" or "Only draw pixels here!".
https://love2d.org/wiki/love.graphics.stencil

You can do much fancier things with shaders by using this too. But for your case. This should be straightforward enough to implement :)

Re: Changing part of image transparency?

Posted: Wed Jul 12, 2017 2:17 pm
by Yaaghër
Thanks for the answer!

I've read and tested stencil before posting but, maybe I'm stupid, I couldn't bring it to change the opacity instead of making the pixel completely invisible.

I think if there is no way to just make the pixels transparent I'll use it anyway.

Re: Changing part of image transparency?

Posted: Wed Jul 12, 2017 2:29 pm
by erasio
The stencil only affects pixels that are drawn while the stencil test is active.

You need to draw everything that should be invisible within it and everything else outside of it ;)

Though honestly. If you just want to have part of it below the map. Why not make that part it's separate sprite and draw it above everything else? Basically making a sandwich.

Static layer (world) -> Dynamic layer (player) -> Static layer (roofs and other player hiding elements)

If you implement a spritelayer system that's super easy to do and allows you to set the layer of individual images!

Re: Changing part of image transparency?

Posted: Wed Jul 12, 2017 2:55 pm
by Yaaghër
I think there maybe a thing I didn't express clearly; I want to do the sandwich's thing as you named it and the Static layer is the one I want to make some part transparent half visible(?): Not invisible, just enough to see what there is under, for example, a wall when the player is behind it.
This would be 2d like zelda, don't starve, or rpg maker's style. For personal preferencies I would like to make, for example, the wall (in Static Layer) that overlap the player, only partially visible.

With stencil it's approximately what I desire but, as I wrote, I would prefere if the wall was partially visible, not just invisible.

Or maybe I just understand what you wrote. Sorry if that's it. My english isn't top notch.

Re: Changing part of image transparency?

Posted: Wed Jul 12, 2017 4:57 pm
by drunken_munki
Yaaghër wrote: Wed Jul 12, 2017 2:55 pm With stencil it's approximately what I desire but, as I wrote, I would prefere if the wall was partially visible, not just invisible.
You use the stencil to mark which pixels you want to draw transparent, then when you are going to draw them you set the transparancy in love.graphics.setColor(255, 255, 255, x) to x, which will control the level of transparency from 0 to 255 (invisible to opaque).

Then you can invert the stencil and you can set the transparancy back to 255 to draw the remaining part of the graphic that you want to be normal.

Re: Changing part of image transparency?

Posted: Wed Jul 12, 2017 9:00 pm
by Yaaghër
Thanks for the answer!

I understand most of what you said, but maybe not the whole thing.
You say to invert the stencil so the remaining part is drawn normaly, this I can't make it work (I tested with code of "Drawing a circle with a hole" in https://love2d.org/wiki/love.graphics.setStencilTest) without redrawing the whole thing after.

What I've now it's: the 'Static Layer' (as called by erasio) is called a first time in which I say where the stencil is used, so a part of the image isn't drawn, then I call again the same image but all with an ~100 alpha so what wasn't drawn in the first call is now drawn but transparent.

I'm not sure it's the best way to do but I know have what I want, I just have to draw the same image two times, which shouldn't be too inconvenient.

Thanks for you two for the answers, it helped.
I'm still curious to know if there is a best way to do it (without calling the same image multiple times), but at least I can move forward!

Re: Changing part of image transparency?

Posted: Sun Jul 16, 2017 6:15 pm
by Luke100000
Yaaghër wrote: Wed Jul 12, 2017 9:00 pm I'm still curious to know if there is a best way to do it (without calling the same image multiple times), but at least I can move forward!
You can use a shader with an additional texture/canvas defining the final alpha channel.

Like this (untested)

Code: Select all

extern Image alpha;
vec4 effect(vec4 color, Image texture, vec2 tc, vec2 sc) {
	float a = Texel(alpha, tc).r;
	vec4 c = Texel(texture, tc);
	return vec4(c.r, c.g, c.b, c.a * a);
}
I hope this is what you want.