With regards to this answer,
Transparent images being generated are darker in shade as in this issue
The given solution to that issue is to add this shader:
shader_type canvas_item; render_mode blend_premul_alpha;
So I took the dark image created from viewport and added it into a TextureRect
as a texture and applied the above shader
but how do I generate an image from this applied shader?
because the only way I found to save images with shaders are by using viewports
(which are causing the problem in the first place, like a recursive problem)
I simply want the viewport.get_texture().get_data().save_png("res://img.png")
image to not be dark in shade
This is what the MergedImg
is suppose to look like:
This is how it actually ends up looking like :
Alright, the issue is that the image will have alpha multiplication done no matter what we do. And arguably it should not. I expected that setting Premultiplied Alpha in import settings would give us the correct result, but it does not※. Instead what works is telling Godot that the image has alpha pre-multiplied via a material/shader… But we don't want to have to do that!
So, as workaround we will fall to alpha division (unmultiplication?). You might not want to do this on image that has lossy compression, because it could reveal compression artifacts. Thankfully that is not the case here.
The code is like this:
var mergeImg=screenshot_viewport.get_texture().get_data()
mergeImg.lock()
for y in mergeImg.get_size().y:
for x in mergeImg.get_size().x:
var color:Color = mergeImg.get_pixel(x, y)
if color.a != 0:
mergeImg.set_pixel(x, y, Color(color.r / color.a, color.g / color.a, color.b / color.a, color.a))
mergeImg.unlock()
mergeImg.save_png(img_path)
And with that the saved image won't have alpha multiplication applied. So we should not tell Godot it has it, so we don't need to use a material to do so.
※: It does the opposite of what we want, it multiplies alpha again.