Texture filter and atlas image distortion problem

Anything libgdx related goes here!

Texture filter and atlas image distortion problem

Postby hellgasm » Sun May 13, 2018 3:25 pm

Hello,

I have a question about premultiplied alpha images, texture atlas and texture filter (minification with bilinear filter).

(I use correct blending function for PMA and all my images are in premultiplied alpha format.)

Suppose that there are 3 different versions of a plain square image:

1. In a separate file, by itself. No padding (padding means alpha 0 pixels in my case).
2. In an atlas in which the subtexture's top left corner(0, 0) is positioned on top left corner(0, 0) of atlas. There are padding on right and bottom but not on left and top.
3. In an atlas, in which there are padding in each of the 4 directions of the subtexture.

Do these 3 give the same result when texture is minified using Bilinear filter? If not I assume this means premultiplied alpha distorts images since alpha 0 pixels are included in interpolation. If so why do we use something that distorts our images?

And even if we don't use premultiplied alpha and use "normal" blending, alpha 0 pixels are still used in interpolation. We add bleeding to overcome problems caused by this (don't know if it causes exact true pixel rendering though). So the question is: Does every texture atlas cause distortion in contained images even if we use bilinear (without mipmaps)? If so why does everyone use atlas if it's something that's so bad?

I tried to test this with a simple scenario but don't know if my test method is right.

I made a yellow square image with red border. The entire square (border included) is 116x116 px. The entire image is 128x128.

I made two versions of this image. Both images are in premultiplied alpha format.

1st version: square starts at 0, 0 and there are 12 pixels padding on bottom and right.
2nd version: square is centered both horizontally and vertically so there are 6px padding on top, left, bottom and right.

I scaled them to 32x32 (scaled entire image without removing padding) using Bilinear filter. And when rendered, they both give very very different results. One is exact while the other one is blurry. I need to know if this is caused by the problem I mentioned in the question.

Here are the images I used in this test:

Image (topleft):
Image

Image (mid):
Image

Render result:
Image

I try to use x, y and width, height values for sprite which match integers so subpixel rendering is not intended.
hellgasm
 
Posts: 6
Joined: Mon Jan 22, 2018 7:25 pm

Re: Texture filter and atlas image distortion problem

Postby tenfour04 » Sun May 13, 2018 8:33 pm

By "distorted" it sounds like what you actually mean is that the edges are blurred or their brightness is incorrect. (Distorted usually means the shape is wrong.)

It also sounds like you have the purpose of pre-multiplied alpha backwards. Using pre-multiplied alpha fixes the issue of edges looking too dark or too light.

In the three cases you described, the ones where the entire texture is filled up or is aligned with a corner will not necessarily have the edge coloring issue, but only if they are perfectly rectangular (no transparent pixels) and if texture wrapping is turned off (unless it's a tiled texture).

So to your main question, why use TextureAtlases if they come with these problems?

1) They aren't problems because we can easily work around them by using padding, bleeding and pre-multiplied alpha.

2) Blurry edges aren't a texture atlas problem. They would happen even without an atlas. They are improved if you use trilinear filtering.

3) TextureAtlases dramatically reduce CPU load when you have more than a few dozen sprites on the screen. It allows SpriteBatch to combine many sprites into a single mesh with a single Texture to draw one time per frame.

With regards to the blurry edges issue, in most games that aren't pixel art, it's going to be rare to have perfectly horizontal or vertical lines in your artwork. If you can afford trilinear filtering, the blurriness won't be noticeable. If you are doing pixel art, you should be using nearest filtering and rounding your camera and game object positions off to align with the pixel grid of the screen. Or alternatively you can render them pixel perfect to a small frame buffer and use an upscaling shader to render that to the screen.
tenfour04
 
Posts: 1182
Joined: Sat Jun 18, 2011 3:24 pm

Re: Texture filter and atlas image distortion problem

Postby hellgasm » Sun May 13, 2018 9:56 pm

By "distorted", I meant it's not the image I expected, it may not be the best word selection, sorry for that.

I know what PMA is and it fixes dark borders and allows proper blending. And I'm not trying to use it backwards.

The plain square image mentioned in those three cases do not contain transparent pixels in square itself. All pixels on the square have alpha of 1. But the entire texture of course have (0, 0, 0, 0) pixels (the space, padding or whatever you call it) as mentioned. I just want to know what happens when there are no (0, 0, 0, 0) pixels to interpolate (when the subtexture touches the edges) on the top and left sides. Would top and left sides of the image be different than bottom and right just because of that? If so I think this means everyone must use separate files instead of texture atlas all the time for proper rendering (I know it provides performance boost but it reduces graphics quality significantly?).

I don't use texture wrapping but have no idea why it matters.

tenfour04 wrote:1) They aren't problems because we can easily work around them by using padding, bleeding and pre-multiplied alpha.

But those workarounds are not enough, I already know them and even use them. Bleeding and pma are mutually exclusive. I use pma blending in my project so I don't need bleeding. Padding fixes texture bleeding from other sub textures but it causes padding itself to bleed and your render is different and worse than it would be with single separate texture file (if I am not mistaken). Maybe I can provide padding in each of 4 directions to make it appear symmetric somehow, but still I don't want to introduce blurring just to use batching with atlas.

tenfour04 wrote:2) Blurry edges aren't a texture atlas problem. They would happen even without an atlas. They are improved if you use trilinear filtering.

In my case it happens when there are transparent pixels in each direction. I'm searching the reason for this. I inspected the bilinear-filter algorithm itself but still its OpenGL implementation is not 100% clear to me. The questions I ask are about bilinear filtering, trilinear filtering is concerned with mipmaps and while they give much better results on minification generally, they also have their own problems in addition to bilinear filter's.
hellgasm
 
Posts: 6
Joined: Mon Jan 22, 2018 7:25 pm

Re: Texture filter and atlas image distortion problem

Postby tenfour04 » Mon May 14, 2018 12:13 am

Your texture that has no padding looks crisp because you are seeing the edges of the polygon that the sprite is mapped to, and antialiasing is turned off. You could achieve the exact same appearance using a texture atlas region that has no transparent pixels around the edges and has bleed padding in the atlas.

In either case, this is only an issue that can only be resolved for sprites that are perfectly rectangular.
tenfour04
 
Posts: 1182
Joined: Sat Jun 18, 2011 3:24 pm


Return to Libgdx

Who is online

Users browsing this forum: No registered users and 1 guest