Como a filtragem anisotrópica é normalmente implementada nas GPUs modernas?

14

A filtragem anisotrópica "mantém a nitidez de uma textura normalmente perdida pelas tentativas da textura do mapa MIP de evitar aliases". O artigo da Wikipedia fornece dicas sobre como pode ser implementado ("sondar a textura (...) para qualquer orientação da anisotropia"), mas não me parece muito claro.

Parece haver várias implementações, conforme sugerido pelos testes ilustrados nas notas da apresentação Modelos aproximados para renderização com base física : insira a descrição da imagem aqui

Quais são os cálculos concretos realizados pelas GPUs (modernas) para escolher o nível MIP correto ao usar a filtragem anisotrópica?

limpe
fonte
3
A especificação para GL_EXT_texture_filter_anisotropicé muito detalhada. Talvez isso ajude você a entender melhor o processo.
glampert

Respostas:

14

O hardware de filtragem de textura coleta várias amostras dos vários níveis do mipmap (a quantidade máxima de amostras é indicada pelo nível de filtragem anisotrópica, embora a quantidade exata de amostras colhidas em uma determinada operação de filtragem dependa da proporção entre os derivados no fragmento. ) Se você projetar o cone visualizando uma superfície em um ângulo oblíquo no espaço da textura, isso resultará em aproximadamente uma projeção de forma oval, mais alongada para ângulos mais oblíquos. Amostras extras são coletadas ao longo do eixo deste oval (dos níveis corretos de mip, para aproveitar a pré-filtragem que eles oferecem) e combinadas para fornecer uma amostra de textura mais nítida.

Outra técnica conhecida como rip-mapping (mencionada no artigo da Wikipedia sobre Mipmapping), que não écomumente encontrado em GPUs contemporâneas, usa pré-filtragem de texturas. Ao contrário dos mips, a textura não é reduzida em escala uniforme, mas usando várias proporções altura-largura (até uma proporção dependente do nível de filtragem anisotrópico escolhido). A variante - ou talvez duas variantes, se usar filtragem trilinear - da textura é então escolhida com base no ângulo da superfície para minimizar a distorção. Os valores de pixel são buscados usando técnicas de filtragem padrão (bilinear ou trilinear). Os mapas de rasgo não são usados ​​em nenhum hardware que eu conheço devido ao seu tamanho proibitivo: enquanto os mipmaps usam armazenamento adicional de 33%, os ripmaps usam 300%. Isso pode ser verificado observando que os requisitos de uso de textura não aumentam ao usar o AF, apenas a largura de banda.

Para uma leitura mais aprofundada, convém dar uma olhada na especificação para a extensão OpenGL EXT_texture_filter_anisotropic . Ele detalha as fórmulas usadas para calcular amostras e como combiná-las ao usar a filtragem anisotrópica.

yuriks
fonte
5
Os mapas RIP também provavelmente não são usados ​​porque não ajudam no caso diagonal, bastante comum. FWIW, se você puder encontrar o código para o Microsoft Refrast, a implementação do filtro anistrópico provavelmente será uma boa referência de como o HW de hoje faz isso.
Simon F
1
"Isso pode ser verificado observando que os requisitos de uso de textura não aumentam ao usar o AF, apenas a largura de banda". Argumento assassino. Boa resposta!
David Kuri 4/15
O link "Rasterização de software de alto desempenho em GPUs" menciona apenas a filtragem anisotrópica de passagem uma vez e não menciona nenhum detalhe. Então, vou editá-lo da resposta, porque não acho que seja relevante de uma maneira útil.
yuriks 9/09/15
@SimonF também podemos acrescentar que o requisito adicional de largura de banda é bastante assustador.
v.oddou 11/09/2015
9

Os requisitos da API podem ser encontrados em qualquer uma das especificações ou extensões. Aqui está um: https://www.opengl.org/registry/specs/EXT/texture_filter_anisotropic.txt

Todos os fornecedores de GPU provavelmente se desviam das especificações porque a qualidade de AF costumava fazer parte de muitos parâmetros de referência. E as implementações atuais continuarão evoluindo à medida que novas cargas de trabalho enfatizam as aproximações existentes. Infelizmente, para saber exatamente o que faz, você precisará fazer parte de uma das empresas. Mas você pode avaliar o espectro de possibilidades nos seguintes documentos, listados em ordem crescente de qualidade e custo de implementação:

Citando as especificações:

 Anisotropic texture filtering substantially changes Section 3.8.5.
 Previously a single scale factor P was determined based on the
 pixel's projection into texture space.  Now two scale factors,
 Px and Py, are computed.

   Px = sqrt(dudx^2 + dvdx^2)
   Py = sqrt(dudy^2 + dvdy^2)

   Pmax = max(Px,Py)
   Pmin = min(Px,Py)

   N = min(ceil(Pmax/Pmin),maxAniso)
   Lamda' = log2(Pmax/N)

 where maxAniso is the smaller of the texture's value of
 TEXTURE_MAX_ANISOTROPY_EXT or the implementation-defined value of
 MAX_TEXTURE_MAX_ANISOTROPY_EXT.

 It is acceptable for implementation to round 'N' up to the nearest
 supported sampling rate.  For example an implementation may only
 support power-of-two sampling rates.

 It is also acceptable for an implementation to approximate the ideal
 functions Px and Py with functions Fx and Fy subject to the following
 conditions:

   1.  Fx is continuous and monotonically increasing in |du/dx| and |dv/dx|.
       Fy is continuous and monotonically increasing in |du/dy| and |dv/dy|.

   2.  max(|du/dx|,|dv/dx|} <= Fx <= |du/dx| + |dv/dx|.
       max(|du/dy|,|dv/dy|} <= Fy <= |du/dy| + |dv/dy|.

 Instead of a single sample, Tau, at (u,v,Lamda), 'N' locations in the mipmap
 at LOD Lamda, are sampled within the texture footprint of the pixel.

 Instead of a single sample, Tau, at (u,v,lambda), 'N' locations in
 the mipmap at LOD Lamda are sampled within the texture footprint of
 the pixel.  This sum TauAniso is defined using the single sample Tau.
 When the texture's value of TEXTURE_MAX_ANISOTROPHY_EXT is greater
 than 1.0, use TauAniso instead of Tau to determine the fragment's
 texture value.

                i=N
                ---
 TauAniso = 1/N \ Tau(u(x - 1/2 + i/(N+1), y), v(x - 1/2 + i/(N+1), y)),  Px > Py
                /
                ---
                i=1

                i=N
                ---
 TauAniso = 1/N \ Tau(u(x, y - 1/2 + i/(N+1)), v(x, y - 1/2 + i/(N+1))),  Py >= Px
                /
                ---
                i=1


 It is acceptable to approximate the u and v functions with equally spaced
 samples in texture space at LOD Lamda:

                i=N
                ---
 TauAniso = 1/N \ Tau(u(x,y)+dudx(i/(N+1)-1/2), v(x,y)+dvdx(i/(N+1)-1/2)), Px > Py
                /
                ---
                i=1

                i=N
                ---
 TauAniso = 1/N \ Tau(u(x,y)+dudy(i/(N+1)-1/2), v(x,y)+dvdy(i/(N+1)-1/2)), Py >= Px
                /
                ---
                i=1 
ap_
fonte