Cómo suavizar texturas cuando se redimensionan en LibGDX (filtros I)

Cuando trabajamos con LibGDX, normalmente usaremos un tamaño de pantalla “virtual” (ya sea mediante el uso de Viewports o con matrices de transformación) con unas dimensiones determinadas, y todas nuestras texturas / imágenes tendrán un tamaño en relación a estas dimensiones.

Si el tamaño del viewport coincide con el tamaño de la pantalla donde se ejecuta nuestro juego, las imágenes se muestran tal y como las hemos creado. Pero si el tamaño real de la pantalla no coincide con las dimensiones del Viewport, éste será escalado para coincidir con el ancho y el alto real de la pantalla (el escalado depende del tipo de viewport que usemos). Cuando ocurre esto, OpenGL utiliza filtros de escalado, que básicamente determinan el algoritmo utilizado para escalar la imagen.

Filtros de escalado

Se dará una explicación más detallada del uso de filtros más adelante (en otro artículo). En esta ocasión nos limitaremos a decir que existen básicamente dos tipos de escalado:

  • GL_NEAREST. Para dibujar cada píxel en pantalla, se utiliza el píxel de la textura (también conocido como “Texel“) que mejor encaja con el píxel que se dibuja en pantalla. Es el filtro utilizado por defecto. Al utilizar directamente un sólo píxel, es un filtro que se aplica rápido, y el resultado es un escalado “duro” (bordes más definidos).
  • GL_LINEAR. Para calcular el color de cada píxel en pantalla, se utiliza una interpolación bilineal a partir de los cuatro píxeles de la textura original más cercanos al píxel que se quiere dibujar en pantalla. El resultado es un escalado mucho más suave. Si bien hay que tener en cuenta que el coste del procesado también es mayor.

A continuación, se muestra una imagen a su tamaño original (izquierda), un escalado con el filtro por defecto GL_NEAREST (centro) y el mismo escalado aplicando el filtro GL_LINEAR (derecha):

original  GL_NEAREST  GL_LINEAR

Aplicar filtros en texturas

Para aplicar un filtro a una determinada textura, basta con llamar al método setFilter() de dicha textura:

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

Estos filtros también se aplican cuando usamos texturas en Actores. Por ejemplo, en este caso cuando se redimensione el actor se aplicará el filtro indicado en la textura:

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

Aplicar filtros en atlas de imágenes

Si utilizamos atlas de imágenes, también podemos usar filtros. Lo haremos indicando el filtro que queremos aplicar en la clave “filter“:

filter: Linear,Linear

Aclaración

Cuando aplicamos filtros a una textura necesitamos indicar dos filtros. Sin entrar en más detalles (lo haremos más adelante), diremos que el primero de ellos se utiliza cuando la imagen se escala a un tamaño menor que la textura original, mientras el segundo filtro indicado se utiliza cuando la imagen se escala a un tamaño mayor que la textura original.

Para terminar…

Aplicando el filtro GL_LINEAR conseguimos que el escalado de nuestras texturas sea más suave. Sin embargo, hay ocasiones en las que no buscamos este efecto. Por ejemplo, pensemos un juego con estética pixelada. En esta ocasión, quizás es más interesante hacer el escalado con el filtro por defecto (GL_NEAREST) para seguir manteniendo los píxeles perfectamente definidos. Es cuestión de probar distintos resultados y decidir si nos conviene usarlos o no.

Saludos,

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>

*