Opengl Texture LoD

LoD selection by opengl

When rendering a textured object, opengl applies filtering on the texture to avoid aliasing artefacts. This is why the texture is loaded in a Mipmap pile. The base level of this pile is the original texture and then every level is built by averaging neighbours texels to create a texture of half the size of the previous one.

mipmap

Then, during rendering, opengl picks the texture from the right LoD. The choice of this LoD is governed by a scale factor  scale_factor. This factor is used to select the LoD level λ

 

lod_selection

 

lod_clamped

 

The bias parameters are either defined by the TEXTURE_LOD_BIAS parameter or by the fragment shader. In λ’, those bias are clamped between -MAX_TEXTURE_LOD_BIAS and MAX_TEXTURE_LOD_BIAS.

This leaves the question of the scale factor scale_factor. It is defined as

scale_formula

Illustrated in 2D

derivative_illustration

Where P(u,v, w) are projected texture coordinates and p(x, y) image coordinates. When using a 1D or 2D texture, the corresponding derivatives are set to 0.

This relies on the fact that when the object is far away from the camera, the point projecting on a pixel will be distant for the points projecting on the neighbouring pixels.

Biasing a LoD

There is therefore two ways to bias a LoD. Either by changing the gradients, therefore altering scale_factor, or by adding a fixed bias.

Fixed Bias

Here, setting the bias during a texture call in the fragment shader or by setting the TEXTURE_LOD_BIAS parameter makes no difference. In our example, we used

texture(sampler, coord, [bias])

in the fragment shader.

Without any bias, we get

color = texture(tex, v_texcoord, 0);
bias_0
Texture from http://www.pusheen.com/

 

If we set a bias to -4, every lod level chosen will be offset by -4. Therefore, when opengl computes lod = 0, 1, 2, 3 or 4, it will use the level lod – 4 = 0.

color = texture(tex, v_texcoord, -4);
bias_minus_4
Texture from http://www.pusheen.com/

 

Oppositely, if we set a bias to 4, the lod levels will be offset by 4, leading to coarser LoD being used.

color = texture(tex, v_texcoord, 4);
bias_4
Texture from http://www.pusheen.com/

 

Changing the gradients

This can be done using the

textureGrad(sampler, coord, dPdx, dPdy)

where dPdx and dPdy and the derivative of the texture coordinates when looking at the neighbouring pixel respectively on the x and y axis.

For a use case, see the Screen Projected Grid post.

Enforcing a LoD

You can force the LoD selection using the function

textureLod(sampler, texture coordinate, lod)

When using the simple texture function, the correct LoD level is chosen automatically by opengl. For example, when rendering an infinite plane, the lod used in the background is not the same as in the foreground.

texture
Texture from http://www.pusheen.com/

 

If we render the same scene using

color = textureLod(tex, v_texcoord, 0);

to force opengl to always use the base texture level, we get

lod_0
Texture from http://www.pusheen.com/

 

We clearly notice aliasing in the background. If we do it the other way around, rendering it using always a high Lod level, we get

color = textureLod(tex, v_texcoord, 6);
lod_6
Texture from http://www.pusheen.com/

Since we are using a texture that is a far average of the original one, the resulting textured plane is heavily blurred.

 

[1] Opengl Specification Version 4.5 – https://www.opengl.org/registry/doc/glspec45.core.pdf

Publicités

Répondre

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion /  Changer )

Photo Google

Vous commentez à l'aide de votre compte Google. Déconnexion /  Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion /  Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion /  Changer )

Connexion à %s