10.3 Filtragem
Na amostragem de texturas, raramente temos um mapeamento \(1:1\) entre texels e pixels. Geralmente, cada pixel corresponde a vários texels, ou um mesmo texel pode ser mapeado a vários pixels.
Tanto o problema de minificação (mais de um texel mapeado para um único pixel) quanto de magnificação (mais de um pixel mapeado para um mesmo texel) exigem o uso de filtros de interpolação para calcular a cor correspondente a uma posição \((u,v)\) no espaço da textura. No OpenGL, o funcionamento desses filtros pode ser configurado de forma independente usando os identificadores GL_TEXTURE_MAG_FILTER
e GL_TEXTURE_MIN_FILTER
com a função glTexParameteri
.
Magnificação
Os filtros de magnificação (GL_TEXTURE_MAG_FILTER
) são dois:
Interpolação por vizinho mais próximo (
GL_NEAREST
): consiste em usar o valor do texel que está mais próximo da posição \((u,v)\) de amostragem, considerando a menor distância Manhattan entre os quatro texels mais próximos. Assim, os texels da textura aumentada têm um aspecto pixelado. Esse modo pode ser habilitado com(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameteri
Interpolação bilinear (
GL_LINEAR
): consiste em realizar uma média entre os quatro texels mais próximos da posição \((u, v)\) de amostragem. Isso é feito calculando a interpolação linear entre dois pares de texels em uma direção (por exemplo, direção \(u\)), e calculando em seguida a interpolação linear dos dois valores resultantes na outra direção (por exemplo, direção \(v\)). Essa é a filtragem padrão do OpenGL. A interpolação bilinear é ativada com(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri
A figura 10.15 mostra a comparação entre os dois filtros em um mesmo detalhe ampliado de textura.
Minificação
Os filtros de minificação do OpenGL (GL_TEXTURE_MIN_FILTER
) também incluem os filtros de interpolação por vizinho mais próximo (GL_NEAREST
) e interpolação bilinear (GL_LINEAR
), e podem ser ativados respectivamente com
(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri
e
(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri
Entretanto, na minificação, é possível que mais do que quatro texels sejam mapeados para um mesmo pixel. Em tais casos, a filtragem bilinear usando somente os quatro vizinhos mais próximos não é suficiente, e erros de aliasing podem ser introduzidos. Uma forma eficiente de reduzir esse problema é através da técnica de mipmapping.
Mipmapping
Um mipmap é uma sequência ordenada de texturas repetidas, cada uma com metade da resolução da textura anterior. O nível base ou nível 0 do mipmap é a textura em sua resolução original. A textura do nível seguinte contém metade da resolução da textura do nível anterior. No último nível do mipmap, a textura tem tamanho \(1 \times 1\). A figura 10.16 mostra todos os níveis de um mipmap para uma textura de resolução \(256 \times 256\).
Se a textura é quadrada e a resolução é uma potência de dois, um texel de um nível do mipmap é definido de tal forma que seu valor é exatamente a média entre quatro texels do nível anterior. Isso pode ser visto na figura 10.17, que mostra o detalhe ampliado dos três últimos níveis do mipmap da figura 10.16. Observe, no nível 8, que a cor do único texel resultante é cinza. Essa cor cinza é a média de todos os texels do nível anterior (nível 7), que é o mesmo que a média de todos os texels da textura. De forma semelhante, no nível 7, o texel mais escuro (canto inferior esquerdo) é a média dos texels de \((0,0)\) até \((0.5, 0.5)\) dos níveis anteriores.
A figura 10.18 mostra uma comparação da qualidade de renderização de um padrão de xadrez sobre um plano, sem e com mipmapping. A renderização sem mapping introduz artefatos de aliasing espacial resultantes da subamostragem.
No OpenGL, um mipmap pode ser gerado facilmente com a função glGenerateMipmap
. Quando a função é chamada, o mipmap é gerado para a textura atualmente ligada com glBindTexture
. Por exemplo,
(GL_TEXTURE_2D, textureID);
glBindTexture(GL_TEXTURE_2D); glGenerateMipmap
gera o mipmap para a textura com identificador textureID
.
Mipmapping é a técnica de filtrar texels usando mipmaps. Quando uma textura com mipmap é amostrada, o amostrador primeiro determina qual nível do mipmap será utilizado. Isso é calculado com base na estimativa do número de texels mapeados para o pixel. Por exemplo, se a área do texel projetado no espaço da janela é tal que todos os texels da textura cabem em um único pixel, então a textura amostrada é a textura do último nível (textura \(1 \times 1\)), pois o texel dessa textura contém a média de todos os texels.
No OpenGL, há diferentes modos de filtragem usando mipmapping (válido apenas para GL_TEXTURE_MIN_FILTER
):
GL_NEAREST_MIPMAP_NEAREST
: escolhe o nível de mipmap que mais se aproxima do tamanho do pixel que está sendo texturizado, e então amostra tal nível usando a interpolação por vizinho mais próximo.GL_LINEAR_MIPMAP_NEAREST
: escolhe o nível de mipmap que mais se aproxima do tamanho do pixel que está sendo texturizado, e então amostra tal nível usando a interpolação bilinear (média dos quatro texels mais próximos).GL_NEAREST_MIPMAP_LINEAR
: escolhe os dois níveis de mipmap que mais se aproximam do tamanho do pixel que está sendo texturizado, e então amostra os dois níveis usando a interpolação por vizinho mais próximo. O valor final é então calculado como a média entre os dois valores amostrados, ponderada de acordo com a proximidade dos níveis de mipmap ao tamanho do pixel. Esse é o modo padrão de filtro de minificação.GL_LINEAR_MIPMAP_LINEAR
: escolhe os dois níveis de mipmap que mais se aproximam do tamanho do pixel que está sendo texturizado, e então amostra os dois níveis usando interpolação bilinear. O valor final é então calculado como a média entre os dois valores amostrados, ponderada de acordo com a proximidade dos níveis de mipmap ao tamanho do pixel.
O modo GL_LINEAR_MIPMAP_LINEAR
também é chamado de interpolação trilinear, pois faz uma interpolação linear sobre dois valores obtidos com interpolação bilinear. Esse é o modo de filtragem que produz resultados com menos artefatos de aliasing, mas também é o mais custoso.