天天看點

Texture Filtering in OpenGLWHAT IS TEXTURE FILTERING?Magnification and minificationTexture filtering modesOPENGL TEXTURE FILTERING MODES

WHAT IS TEXTURE FILTERING?

Textures in OpenGL are made up of arrays of elements known as texels, which contain colour and alpha values. This corresponds with the display, which is made up of a bunch of pixels and displays a different colour at each point. In OpenGL, textures are applied to triangles and drawn on the screen, so these textures can be drawn in various sizes and orientation. The texture filtering options in OpenGL tell it how to filter the texels onto the pixels of the device, depending on the case.

There are three cases:

  • Each texel maps onto more than one pixel. This is known as magnification.
  • Each texel maps exactly onto one pixel. Filtering doesn’t apply in this case.
  • Each texel maps onto less than one pixel. This is known as minification.

OpenGL lets us assign a filter for both magnification and minification, and lets us use nearest-neighbour, bilinear filtering, or trilinear filtering. I will explain what these mean further below.

Magnification and minification

Magnification

Texture Filtering in OpenGLWHAT IS TEXTURE FILTERING?Magnification and minificationTexture filtering modesOPENGL TEXTURE FILTERING MODES

As you can see, the texels of the image are easily visible, as they now cover many of the pixels on your display.

Minification

Texture Filtering in OpenGLWHAT IS TEXTURE FILTERING?Magnification and minificationTexture filtering modesOPENGL TEXTURE FILTERING MODES

With minification, many of the details are lost as many of the texels cannot be rendered onto the limited pixels available.

Texture filtering modes

Nearest

The texels of a texture are clearly visible as large squares in the magnification example when no interpolation between the texel values are done. When rendering is done in nearest-neighbour mode, the pixel is assigned the value of the nearest texel.

Bilinear Interpolation

Instead of assigning the values of a group of pixels to the same nearby texel value, these values will instead be linearly interpolated between the neighbouring four texels. Bilinear interpolation is mostly useful for magnification. It can also be used for minification, but beyond a certain point and we run into the same problem that we are trying to cram far too many texels onto the same pixel. OpenGL will only use at most 4 texels to render a pixel, so a lot of information is still being lost.

Mipmapping

How can we minify textures without introducing noise and use all of the texels? This can be done by generating a set of optimized textures at different sizes which we can then use at runtime. Since these textures are pre-generated, they can be filtered using more expensive techniques that use all of the texels, and at runtime OpenGL will select the most appropriate level based on the final size of the texture on the screen.

Texture Filtering in OpenGLWHAT IS TEXTURE FILTERING?Magnification and minificationTexture filtering modesOPENGL TEXTURE FILTERING MODES

The resulting image can have more detail, less noise, and look better overall. Although a bit more memory will be used, rendering can also be faster, as the smaller levels can be more easily kept in the GPU’s texture cache. Let’s take a closer look at the resulting image at 1/8th of its original size, using bilinear filtering without and with mipmaps; the image has been expanded for clarity:

OPENGL TEXTURE FILTERING MODES

OpenGL has two parameters that can be set:

GL_TEXTURE_MIN_FILTER
GL_TEXTURE_MAG_FILTER
           

These correspond to the minification and magnification described earlier.

GL_TEXTURE_MIN_FILTER

accepts the following options:

GL_NEAREST
GL_LINEAR
GL_NEAREST_MIPMAP_NEAREST
GL_NEAREST_MIPMAP_LINEAR
GL_LINEAR_MIPMAP_NEAREST
GL_LINEAR_MIPMAP_LINEAR
           

GL_TEXTURE_MAG_FILTER

accepts the following options:

GL_NEAREST
GL_LINEAR
           

GL_NEAREST

corresponds to nearest-neighbour rendering,

GL_LINEAR

corresponds to bilinear filtering,

GL_LINEAR_MIPMAP_NEAREST

corresponds to bilinear filtering with mipmaps, and

GL_LINEAR_MIPMAP_LINEAR

corresponds to trilinear filtering. Graphical examples and further explanation of the most common options are visible further down in this lesson.

How to set a texture filtering mode

We first need to bind the texture, then we can set the appropriate filter parameter on that texture:

GLES20.glBindTexture(GLES20.GL_TEXTURE_2D, mTextureHandle);
GLES20.glTexParameteri(GLES20.GL_TEXTURE_2D, GLES20.GL_TEXTURE_MIN_FILTER, filter);
           

How to generate mipmaps

This is really easy. After loading the texture into OpenGL, while the texture is still bound, we can simply call:

This will generate all of the mipmap levels for us, and these levels will get automatically used depending on the texture filter set.

繼續閱讀