Page 1 of 1

[SOLVED] Help with Replacing the alpha value of one texture with another.

Posted: Sun Mar 12, 2023 12:33 am
by CinderRose
I'm essentially trying to use an image as a stencil. I want to take a texture and replace the alpha value of every pixel with the the alpha value of a masking image.
I tried https://love2d.org/wiki/love.graphics.stencil to some success, but the alpha is all or nothing and the edges of things look too sharp.

I made a function that goes through the image pixel by pixel and replaces the alpha values, but it's too resource intensive. Here is the function in case it helps clarify what I'm trying to do.

Code: Select all

local ImageData = love.image.newImageData("path/file/texture.png")
local Image = love.graphics.newImage("path/file/texture.png")
local MaskData = love.image.newImageData("path/file/mask.png")

function Mask(img, imgData, maskData)
	
    
    local width, height = img:getDimensions()

    for x = 0, width -1 do
        for y = 0, height -1 do 
			--loops through every pixel of the image
            
			local r1, g1, b1 = imgData:getPixel(x, y)
			--gets the RGB values of each pixel of the texture
			
            local r2, g2, b2, a2 = maskData:getPixel(x, y)
			--gets the alpha value for each pixel from the mask,
            
            imgData:setPixel(x, y, r1, g1, b1, a2)
			--[[Reassigns things. 
				The texture keeps all of its original RBG values, 
				but gets the corresponding alpha from the mask.]]
        end
    end
	
    img:replacePixels(imgData)
    --pushes the updated data to the original image.
end

function love.draw()
	
	Mask (Image, ImageData, MaskData)

	love.graphics.draw(Image, 0, 0)
	--[[It works and is fine for a one time call.
		However doing it every frame is too much and tanks the frame rate.]]
end
The texture and the mask will be dynamic so it needs to be called every frame.

I could store all of the pixel data in tables and iterate over them instead of calling "getPixel", but I don't know if that would be less resource intensive.

That said, I suspect using a shader will handle the issue (since the shader I did use didn't tank the frame rate).
However, I am very unfamiliar with GLSL and trying to use the shader with OpenGL scares and confuses me.

I found this thread https://love2d.org/forums/viewtopic.php?p=228590 which seems to be trying to do something similar, but again I don't know enough about the shader to get it working.

If I made the function wrong and am needlessly wasting resource, or if you have any advice on how to get a shader to swap texture alpha I would very much appreciate the help.

Re: Help with Replacing the alpha value of one texture with another.

Posted: Sun Mar 12, 2023 2:14 am
by keharriso
I think you're right about shaders being the way to go. Try this one:

Code: Select all

local Image = love.graphics.newImage("path/file/texture.png")
local Mask = love.graphics.newImage("path/file/mask.png")

local MaskShader = love.graphics.newShader[[
uniform Image mask;

vec4 effect(vec4 color, Image tex, vec2 texture_coords, vec2 screen_coords)
{
	vec4 tex_color = Texel(tex, texture_coords);
	vec4 mask_color = Texel(mask, texture_coords);
	tex_color.a = mask_color.a;
	return tex_color;
}
]]

function love.draw()
	MaskShader:send("mask", Mask)
	love.graphics.setShader(MaskShader)
	love.graphics.draw(Image, 0, 0)
end

Re: Help with Replacing the alpha value of one texture with another.

Posted: Sun Mar 12, 2023 2:45 am
by CinderRose
keharriso wrote: Sun Mar 12, 2023 2:14 am I think you're right about shaders being the way to go. Try this one:
Yo it works!
The syntax is a little confusing, but I think I understand how it works.

Much appreciated, thank you <3