AA creating gaps between fills

191 views
Skip to first unread message

Jeru Sanders

unread,
Apr 24, 2021, 3:43:42 PM4/24/21
to skia-discuss
I'm using Skia to render vectors that came from an SWF parser that wrote, it was a hassle but, looks good in most cases.

But when using paint.setAntiAlias(true), adjacent fills seem to leave gaps where the background can be seen. I've read some stuff about Skia's AA implementation and half pixels, it seems like I could technically solve this by inflating all the vector graphics by ~0.5px.

I can almost imagine calculating the normal of each line and bezier curve then moving everything out by a small amount at load time, does that sound like a reasonable solution?

skiaAA.png

Christopher Dalton

unread,
Apr 24, 2021, 6:18:51 PM4/24/21
to skia-d...@googlegroups.com
You are correct. Skia's antialiasing works by blending the outer 1px of a fill into the canvas, so those artifacts on your edge are working as intended. Flash does not work the same way, which is why your edges look clean there.

If you don't want the gaps you can do outsetting as you suggested, or you can also render to a multisampled GPU surface. MSAA will treat edges the same way Flash does, and it will probably also render Flash content faster than anything else in Skia.

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/10ef3419-aedf-46b2-9010-54a064718a76n%40googlegroups.com.

paul....@gmail.com

unread,
Apr 25, 2021, 6:32:11 AM4/25/21
to skia-discuss
You might want to consider a simpler approach than mathematically outsetting the shape.  Simply apply a 1px stroke that is the same as the fill colour.

Jeru Sanders

unread,
Apr 25, 2021, 11:06:10 AM4/25/21
to skia-discuss
Thanks for the info, I don't actually know anything about outsetting. I'll try the stroke thing, but I get the feeling that's gonna be slow. After that I'll probably try the gpu surface thing, I was using it earlier, but it seemed slower than using the cpu, and messed with the gpu state all the time.

Luboš Luňák

unread,
Apr 26, 2021, 5:24:06 AM4/26/21
to skia-d...@googlegroups.com
See also the discussion at
https://groups.google.com/g/skia-discuss/c/NlKpD2X_5uc/m/Vuwd-kyYBwAJ for a
similar problem.

--
Luboš Luňák
l.l...@collabora.com

Jeru Sanders

unread,
May 1, 2021, 12:59:22 PM5/1/21
to skia-discuss
Following up on this, I did the 1px stroke solution and it worked beautifully. I can draw my fills without AA and just draw the same path with a stroke paint using AA to make the edges look nice. I still have to draw my strokes with AA though, luckily my art is 90% fills, this method even preforms better than just turning AA on for fills.

It makes me wonder why this isn't the default method of AA, and why strokes even exist instead of being converted into fills.

The only issue is that tiny things look a little bit thicker, but it's hardly noticeable in my project.

Pedro Arthur

unread,
May 1, 2021, 1:56:13 PM5/1/21
to skia-d...@googlegroups.com
Em sáb., 1 de mai. de 2021 às 13:59, Jeru Sanders
<jerus...@gmail.com> escreveu:
>
> Following up on this, I did the 1px stroke solution and it worked beautifully. I can draw my fills without AA and just draw the same path with a stroke paint using AA to make the edges look nice. I still have to draw my strokes with AA though, luckily my art is 90% fills, this method even preforms better than just turning AA on for fills.
>
> It makes me wonder why this isn't the default method of AA, and why strokes even exist instead of being converted into fills.
I think it may not work as intended if you have semi-transparent
fills. I'm not 100% sure but I guess skia converts stroke into fills
internally.

>
> The only issue is that tiny things look a little bit thicker, but it's hardly noticeable in my project.
>
> On Monday, April 26, 2021 at 3:24:06 AM UTC-6 l.l...@collabora.com wrote:
>>
>> On Saturday 24 of April 2021, Jeru Sanders wrote:
>> > I'm using Skia to render vectors that came from an SWF parser that wrote,
>> > it was a hassle but, looks good in most cases.
>> >
>> > But when using paint.setAntiAlias(true), adjacent fills seem to leave gaps
>> > where the background can be seen. I've read some stuff about Skia's AA
>> > implementation and half pixels, it seems like I could technically solve
>> > this by inflating all the vector graphics by ~0.5px.
>> >
>> > I can almost imagine calculating the normal of each line and bezier curve
>> > then moving everything out by a small amount at load time, does that sound
>> > like a reasonable solution?
>>
>> See also the discussion at
>> https://groups.google.com/g/skia-discuss/c/NlKpD2X_5uc/m/Vuwd-kyYBwAJ for a
>> similar problem.
>>
>> --
>> Luboš Luňák
>> l.l...@collabora.com
>
> --
> You received this message because you are subscribed to the Google Groups "skia-discuss" group.
> To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
> To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/08b8543e-af1f-40c5-84ad-8b82e966aea9n%40googlegroups.com.

Christopher Dalton

unread,
May 1, 2021, 4:04:57 PM5/1/21
to skia-d...@googlegroups.com
Glad to hear it! Yes that's a good idea to turn off AA for your fill- that allows you to use tessellation for the fills instead. (Are you using th GPU backend?) You might want to try a stroke width of 0 though. That enables hairline stroking, which will always be 1px wide, regardless of transform matrix.

>> It makes me wonder why this isn't the default method of AA

Also a very interesting question. By stroking the path you aren't quite filling the exact beziers - you are filling in .5px outset curves. There also will be considerations if your paint has transparency. But I have also been ruminating on this concept of using strokes to smooth the outer edge of fills since you started this email thread. Ultimately Skia is moving toward using MSAA for antialiasing, but think some type of stroking might be a really good backup for GPUs that don't support MSAA well.

--

Peter Verswyvelen

unread,
May 1, 2021, 4:44:28 PM5/1/21
to skia-d...@googlegroups.com
Just out of curiosity, if you are using a GPU backend, what performance are you getting when justing doing super sampling? E.g. render without anti aliasing to an offscreen bitmap that is e.g. 4x4 times bigger, then downscale using a bicubic filter...

MSAA approximates that in hardware...

GPUs these days are so fast, that I wanted to mention this approach 


paul....@gmail.com

unread,
May 2, 2021, 5:53:59 AM5/2/21
to skia-discuss
csmart... wrote:
> You might want to try a stroke width of 0 though.

Yes. I agree. Ths is a good point, and what I should have said.


>  I think it may not work as intended if you have semi-transparent
> fills. I'm not 100% sure but I guess skia converts stroke into fills
> internally.

If you have a translucent fill, then instead of drawing with alpha on the colour,  you can do:

saveLayerAlpha(bounds, alpha);
// draw the fill width solid colour
// draw the stroke with solid colour
restore();


Paul

craste...@gmail.com

unread,
May 2, 2021, 7:42:56 PM5/2/21
to skia-discuss
Using the stroke method is not just a problem for semi-transparent filled shapes;  but also for filled shapes with blendmodes active.

craste...@gmail.com

unread,
May 2, 2021, 8:31:05 PM5/2/21
to skia-discuss
I think MSAA is the only method to fix this problem without any special cases.

Jeru Sanders

unread,
May 2, 2021, 9:17:42 PM5/2/21
to skia-discuss
Most of these issues don't come up in my case, blendmodes are pretty niche. Except for the SUBTRACT blendmode, which seems to be conspicuously missing anyways.
I can conserve alpha by using: aaStrokePaint.setAlpha(fillPaint.getAlpha())
But it doesn't work on gradients without more thinking, as soon as that comes up I'll probably try the gpu MSAA method again.

Skia gpu seems to mess with your opengl state in a kinda unexplained way, at the end of each frame I glTexSubImage2D a 1920x1080 bitmap from Skia into my engine.
I'd ideally want to put it in on another thread and stream it, but I'm not sure how that's gonna work with Skia issuing opengl calls.

craste...@gmail.com

unread,
May 2, 2021, 11:59:20 PM5/2/21
to skia-discuss
What do you mean by "subtract" blendmode?  Erasing?  
Reply all
Reply to author
Forward
0 new messages