Ajude-me a entender a Filtragem Anisotrópica (AF)

8

Ultimamente, tenho lido sobre filtragem de texturas, como filtragem de vizinhos mais próximos, filtragem bilinear, filtragem trilinear, filtragem anisotrópica, mapas MIP, mapas RIP e assim por diante.

De uma perspectiva de alto nível, acho que consigo entender essas técnicas, como o trabalho e por que elas existem, com exceção da filtragem anisotrópica. A filtragem anisotrópica está me deixando louco.

Percebo o problema de precisar texturizar uma superfície em ângulo em relação à câmera, mas não entendo como a amostragem de pegadas trapezoidais poderia resolver isso (embora eu possa ver o resultado). Provavelmente, isso é porque eu NÃO entendo como a pegada trapezoidal é calculada e como os telex anexos são ponderados para provar a textura.

Este artigo da Nvidia me confunde ainda mais usando frases como " quando um texel é trapezoidal " ou " a filtragem anisotrópica escala a altura ou a largura de um mapa mip em uma proporção relativa à distorção da perspectiva da textura ". Texel trapezoidal? Dimensionando um mapa MIP? O que isso significa?

Você poderia me ajudar a entender como os níveis de AF e AF funcionam?

Observe que meu objetivo não é ter uma implementação OpenGL ou DirectX AF, mas entender como o AF funciona de uma perspectiva de alto nível.

Nicola Masotti
fonte

Respostas:

10

Para entender a natureza da filtragem anisotrópica, você precisa ter um entendimento firme do que realmente significa o mapeamento de textura.

O termo "mapeamento de textura" significa atribuir posições em um objeto a locais em uma textura. Isso permite que o rasterizador / sombreador busque, para cada posição no objeto, os dados correspondentes da textura. O método tradicional para fazer isso é atribuir a cada vértice de um objeto uma coordenada de textura, que mapeia diretamente essa posição para um local na textura. O rasterizador interpola essa coordenada de textura pelas faces dos vários triângulos para produzir a coordenada de textura usada para buscar a cor da textura.

Agora, vamos pensar no processo de rasterização. Como isso funciona? Ele pega um triângulo e o divide em blocos do tamanho de pixels que chamaremos de "fragmentos". Agora, esses blocos de tamanho de pixel são do tamanho de pixel em relação à tela.

Mas esses fragmentos não têm tamanho de pixel em relação à textura. Imagine se nosso rasterizador gerasse uma coordenada de textura para cada canto do fragmento. Agora imagine desenhar esses quatro cantos, não no espaço da tela, mas no espaço da textura . Que forma seria essa?

Bem, isso depende das coordenadas da textura. Ou seja, depende de como a textura é mapeada para o polígono. Para qualquer fragmento em particular, pode ser um quadrado alinhado ao eixo. Pode ser um quadrado não alinhado ao eixo. Pode ser um retângulo. Pode ser um trapézio. Pode ser praticamente qualquer figura de quatro lados (ou pelo menos convexa).

Se você estivesse acessando a textura corretamente, a maneira de obter a cor da textura para um fragmento seria descobrir qual é esse retângulo. Em seguida, busque cada texel da textura dentro desse retângulo (usando a cobertura para dimensionar as cores que estão na borda). Então avalie-os todos juntos. Isso seria um mapeamento de textura perfeito.

Também seria extremamente lento .

No interesse do desempenho, tentamos aproximar a resposta real. Baseamos as coisas em uma coordenada de textura, em vez das 4 que cobrem toda a área do fragmento no espaço texel.

A filtragem baseada em Mipmap usa imagens de resolução mais baixa. Essas imagens são basicamente um atalho para o método perfeito, calculando previamente como seriam os grandes blocos de cores quando combinados. Portanto, quando seleciona um mapa mip mais baixo, ele usa valores pré-calculados em que cada texel representa uma área da textura.

A filtragem anisotrópica funciona aproximando o método perfeito (que pode e deve ser acoplado ao mipmapping) através da captura de um número fixo de amostras adicionais. Mas como ele descobre a área no espaço texel para buscar, uma vez que ainda é dada apenas uma coordenada de textura?

Basicamente, ele trapaceia. Como os sombreadores de fragmento são executados em blocos vizinhos 2x2, é possível calcular a derivada de qualquer valor no sombreador de fragmento no espaço de tela X e Y. Em seguida, usa essas derivadas, juntamente com a coordenada de textura real, para calcular uma aproximação de qual seria a pegada de textura do verdadeiro fragmento. E, em seguida, ele executa várias amostras nessa área.

Aqui está um diagrama para ajudar a explicá-lo:

Pegada de fragmentos e amostras anisotrópicas.  FYI: se você já viu isso antes, é meu.

Os quadrados em preto e branco representam nossa textura. É apenas um tabuleiro de damas de 2x2 texels branco e preto.

O ponto laranja é a coordenada da textura do fragmento em questão. O contorno vermelho é a pegada do fragmento, centralizada na coordenada da textura.

As caixas verdes representam os texels que uma implementação de filtragem anisotrópica pode acessar (os detalhes dos algoritmos de filtragem anisotrópica são específicos da plataforma, portanto, só posso explicar a idéia geral).

Este diagrama em particular sugere que uma implementação pode acessar 4 texels. Ah, sim, as caixas verdes cobrem 7 delas, mas a caixa verde no centro pode ser buscada em um mapa mip menor, buscando o equivalente a 4 texels em uma busca. Obviamente, a implementação ponderaria a média dessa busca em 4 em relação às únicas texel.

Se o limite de filtragem anisotrópica fosse 2 em vez de 4 (ou superior), a implementação selecionaria 2 dessas amostras para representar a pegada do fragmento.

Nicol Bolas
fonte
Obrigado por explicar isso e desculpe pela resposta atrasada, mas tive que encontrar tempo para ler isso com muito cuidado. Sinto que o único parágrafo que não entendo completamente é aquele em que você fala sobre sombreadores e derivados de fragmentos. O que exatamente é derivado no espaço da tela X e Y? É o valor da coordenada da textura?
Nicola Masotti
@NicolaMasotti: "Derivativo" é um termo de cálculo. Nesse caso, é a taxa de alteração da coordenada da textura, na superfície do triângulo, no espaço da tela X ou Y. Se você não conhece o cálculo, não vou poder explicá-lo para você em uma única postagem.
Nicol Bolas
Felizmente eu sei o que é um derivado. Existe algum lugar onde eu possa procurar a matemática exata?
Nicola Masotti
Além disso, eu proporia algumas alterações na sua resposta, ou seja, " depende de como o polígono é mapeado para a textura " em vez de " depende de como a textura é mapeada para o polígono ". Além disso, quando você diz: " usando a cobertura para dimensionar cores que estão na borda ", na verdade você quer dizer " cores de peso que estão na borda "?
Nicola Masotti 8/17
3

Alguns pontos que você provavelmente já conhece, mas que eu só quero colocar lá fora para os outros que estão lendo isso. A filtragem nesse caso refere-se à filtragem passa-baixa, como você pode obter em um Gaussian Blur ou em um desfoque de caixa. Precisamos fazer isso porque estamos pegando algumas mídias com altas frequências e transformando-as em um espaço menor. Se não o filtrássemos, obteríamos artefatos de alias, o que ficaria ruim. Portanto, filtramos as frequências que são muito altas para serem reproduzidas com precisão na versão em escala. (E passamos as frequências baixas, então usamos um filtro "passa-baixo" como um borrão.)

Então, vamos pensar sobre isso primeiro do ponto de vista de um borrão. Um desfoque é um tipo de convolução. Nós pegamos o kernel de convolução e multiplicamos por todos os pixels em uma área e depois os adicionamos e dividimos pelo peso. Isso nos dá a saída de um pixel. Em seguida, movemos e repetimos para o próximo pixel repetido, etc.

É muito caro fazer dessa maneira, então há uma maneira de trapacear. Alguns núcleos de convolução (particularmente um kernel Gaussiano de desfoque e um kernel de desfoque de caixa) podem ser separados em uma passagem horizontal e vertical. Você pode filtrar tudo com apenas um kernel horizontal primeiro, depois pegar o resultado e filtrá-lo apenas com um kernel vertical, e o resultado será idêntico ao cálculo mais caro em todos os pontos. Aqui está um exemplo:

Original:

Havaí

Borrão horizontal:

Havaí turva horizontalmente

Horizontal seguido de Desfoque vertical:

Havaí turva horizontalmente e depois verticalmente

Assim, podemos separar a filtragem em um passe vertical e horizontal. E daí? Bem, acontece que podemos fazer a mesma coisa para transformações espaciais. Se você pensa em uma rotação de perspectiva, assim:

Havaí Girado em torno do eixo Y

Pode ser dividido em uma escala X:

insira a descrição da imagem aqui

seguido por uma escala de cada coluna por uma quantidade ligeiramente diferente:

Havaí escalado em X e depois proporcionalmente em Y

Então agora você tem duas operações de dimensionamento diferentes. Para que a filtragem seja correta, convém filtrar mais fortemente em X do que em Y e filtrar por uma quantidade diferente para cada coluna. A primeira coluna não recebe filtragem porque é do mesmo tamanho que o original. A segunda coluna fica um pouco mais pequena porque é um pouco menor que a primeira, etc. A última coluna recebe a maior quantidade de filtragem de qualquer coluna.

A palavra "anisotropia" vem do grego "an" significa "não", "isos" significa igual e "tropos" significa "direção". Portanto, significa "não é igual em todas as direções". E é exatamente isso que vemos - a escala e a filtragem são feitas em diferentes quantidades em cada direção.

user1118321
fonte