How to smooth textures when they are resized in LibGDX (filters I)

When working with LibGDX, we normally use a “vitual” screen (whether through using Viewports or with transformation matrices) with a defined dimensions, and all textures / images will have a size according to that virtual dimensions.

If the viewport size matches with the real size of the screen where our game is running, the textures are shown as we have created they. On the other hand, if the dimensions of the real screen does not match with our viewport world size, this will be scaled to match with the real width and height of the screen (the scaling will be done depending of the viewport type). When this happens, OpenGL uses texture filters, which basically define the algorithm used to scale the textures.

Texture filters

A further explanation will be given later (in another article). This time I will only say that there are basically two types of filters:

  • GL_NEAREST. To represent each pixel on the screen, it is used the pixel of the texture (texel) that best matches to the pixel of the screen. This is the default filter. As this filter only uses one texel for every pixel on the screen, its a very quickly to apply filter. The result is an image with “hard” borders.
  • GL_LINEAR. To represent each pixel on the screen, it is used a bilinear interpolation taking the four closest texels that best match with the screen pixel. The result is a smooth scaling. But its important to consider that the processing costs will also be bigger than GL_NEAREST.

Below, it’s shown a texture in its original size (left), a resized version with default GL_NEAREST (center) and then another resized version using GL_LINEAR (right):

original GL_NEAREST GL_LINEAR

Applying filters on textures

To apply a filter in a texture, we only need to set it with setFilter() method:

Texture myTexture = new Texture( Gdx.files.internal("texture.png") );
myTexture.setFilter(Textue.TextureFilter.Linear, Textue.TextureFilter.Linear);

Filters also applies when the textures are used in actors. For example, in the next case when the actor will be scaled, the filter Texture.TextureFilter.Linear (GL_LINEAR) will be used:

Texture actorTexture = new Texture( Gdx.files.internal("texture.png") );
actorTexture.setFilter(Textue.TextureFilter.Linear, Textue.TextureFilter.Linear);
Image imageActor = new Image(actorTexture);

Applying filters on texture atlases

If we use texture atlases, we can also use filters. We do this by setting the filter with the key “filter” on .atlas file:

filter: Linear,Linear

Clarification

When we specify the filter applied to a texture, we need to indicate two filters. Without going into too many details (this will take place in another post), the first filter is used when the texture is minimized, and the second one is used when the texture is maximized.

At last…

Applying the GL_LINEAR filter we get our textures with a smooth scaling. However, there are situations where we don’t need this effect. For example, consider a game with pixelated aesthetics. This time, maybe is more interesting to scale using the default filer (GL_NEAREST) to preserve the pixelated aesthetics. We can test different filter and choose which one is better in each case.

Regards,

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

*