Skip to content

Unclipped Paint operations replace alpha channel on the whole target surface #157

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
jpbruyere opened this issue Mar 3, 2025 · 2 comments
Labels
TODO to do..

Comments

@jpbruyere
Copy link
Owner

jpbruyere commented Mar 3, 2025

When painting an image on a surface that have already some content without clipping the paint with a path or a clipping operation, the alpha channel of the whole target surface is affected, and set to 0 even where the source surface is no drawn, making previous content invisible (colors are still present, but alpha is 0)

The following code reproduce the problem:

VkvgContext ctx = vkvg_create(surf);
VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
VkvgSurface imgSurf2 = vkvg_surface_create_from_image(device, imgPath3);

vkvg_set_source_surface(ctx, imgSurf, 0, 0);
vkvg_paint(ctx);

vkvg_set_source_surface(ctx, imgSurf2, 50, 50);
vkvg_paint(ctx);

vkvg_surface_destroy(imgSurf2);
vkvg_surface_destroy(imgSurf);
vkvg_destroy(ctx);

A simple workaround for now is to clip the drawing either with a path or a clipping operation:

VkvgContext ctx = vkvg_create(surf);
VkvgSurface imgSurf = vkvg_surface_create_from_image(device, imgPath);
VkvgSurface imgSurf2 = vkvg_surface_create_from_image(device, imgPath3);

vkvg_set_source_surface(ctx, imgSurf, 0, 0);
vkvg_paint(ctx);

vkvg_set_source_surface(ctx, imgSurf2, 50, 50);
vkvg_rectangle(ctx, 50,50,200,200);//Image paint is clipped inside this path
vkvg_paint(ctx);

vkvg_surface_destroy(imgSurf2);
vkvg_surface_destroy(imgSurf);
vkvg_destroy(ctx);

On screen, the problem should not appear, because swapchain's images have no alpha channel, but when saving to png with vkvg_surface_write_to_png(surf, "test.png"); the problem appears.

I'm not completely sure this should be considered as a bug. Paint(ctx) calls do full surface painting, if VKVG_EXTEND_* are used, affecting the whole target is the expected behavior. Default image extend is VKVG_EXTEND_NONE, if preventing affecting the whole alpha channel imply small or easy changes, this could be corrected. If not, the current behavior should be explained in documentation.

@jpbruyere jpbruyere added the TODO to do.. label Mar 3, 2025
@173619070
Copy link

I didn't use your vkvg project to try rendering multiple images. Instead, I wrote a Vulkan project myself to render multiple images, and it has been successfully implemented. The effect is great. This new project has its own VkPipelineLayout and VkPipeline, as well as its own Shader. I'm currently modifying your vkvg code, and I plan to incorporate the code of my new project into your vkvg project. This will be a substantial amount of work. If I manage to implement it later, I will also upload it to GitHub. Thank you for your explanation, and I will also keep a close eye on this issue.

@jpbruyere
Copy link
Owner Author

I think I found the problem. When loading an image with alpha into a new surface (vkvg_surface_create_from_bitmap), the blit operation used to copy the pixels is not affecting region with alpha set to 0, so the resulting image surface was having some undefined pixels.
I added a surface clear operation before the blit, and the problem looks solved. I'll push to master the correction.

Image

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
TODO to do..
Projects
None yet
Development

No branches or pull requests

2 participants