Aiutami a capire il filtro anisotropico (AF)


8

Ultimamente ho letto il filtro delle trame, vale a dire il filtro del vicino più vicino, il filtro bilineare, il filtro trilineare, il filtro anisotropico, le mappe MIP, le mappe RIP e così via.

Da una prospettiva di alto livello penso di poter comprendere queste tecniche, come funzionano e perché esistono, ad eccezione del filtraggio anisotropico. Il filtro anisotropico mi sta facendo impazzire.

Riesco a vedere il problema di dover testurizzare una superficie inclinata rispetto alla telecamera, ma non riesco a capire come il campionamento delle impronte trapezoidali possa risolvere questo problema (anche se riesco a vedere il risultato). Questo probabilmente perché NON capisco come viene calcolata l'impronta trapezoidale e come vengono ponderati i telex racchiusi per campionare la trama.

Questo articolo di Nvidia mi confonde ancora di più usando frasi come " quando un texel è trapezoidale " o "il filtro anisotropico ridimensiona l'altezza o la larghezza di una mipmap di un rapporto relativo alla distorsione prospettica della trama ". Texel trapezoidale? Ridimensionare una MIPmap? Cosa significa questo?

Potresti aiutarmi a capire come funzionano i livelli di AF e AF?

Si noti che il mio obiettivo NON è quello di avere un'implementazione AF OpenGL o DirectX, ma piuttosto di capire come funziona AF da una prospettiva di alto livello.

Risposte:


10

Per comprendere la natura del filtro anisotropico, è necessario avere una solida conoscenza di cosa significhi realmente la mappatura delle trame.

Il termine "mappatura delle trame" significa assegnare posizioni su un oggetto a posizioni in una trama. Ciò consente al rasterizzatore / shader di, per ogni posizione sull'oggetto, recuperare i dati corrispondenti dalla trama. Il metodo tradizionale per fare ciò consiste nell'assegnare a ciascun vertice su un oggetto una coordinata di trama, che mappa direttamente quella posizione su una posizione nella trama. Il rasterizzatore interpolerà questa coordinata di trama attraverso le facce dei vari triangoli per produrre la coordinata di trama utilizzata per recuperare il colore dalla trama.

Ora, pensiamo al processo di rasterizzazione. Come funziona? Prende un triangolo e lo scompone in blocchi di dimensioni pixel che chiameremo "frammenti". Ora, questi blocchi di dimensioni pixel hanno dimensioni di pixel rispetto allo schermo.

Ma questi frammenti non hanno dimensioni in pixel rispetto alla trama. Immagina se il nostro rasterizzatore generasse una coordinata di trama per ogni angolo del frammento. Ora immagina di disegnare quei 4 angoli, non nello spazio dello schermo, ma nello spazio delle trame . Che forma sarebbe?

Bene, questo dipende dalle coordinate della trama. Cioè, dipende da come la trama è mappata sul poligono. Per ogni particolare frammento, potrebbe essere un quadrato allineato agli assi. Potrebbe essere un quadrato non allineato sull'asse. Potrebbe essere un rettangolo. Potrebbe essere un trapezio. Potrebbe essere praticamente qualsiasi figura a quattro facce (o almeno, quelle convesse).

Se si stesse eseguendo correttamente l'accesso alla trama, il modo per ottenere il colore della trama per un frammento sarebbe capire qual è questo rettangolo. Quindi recupera ogni texel dalla trama all'interno di quel rettangolo (usando la copertura per ridimensionare i colori che si trovano sul bordo). Quindi fai una media di tutti insieme. Sarebbe una perfetta mappatura delle trame.

Sarebbe anche estremamente lento .

Nell'interesse della performance, cerchiamo invece di approssimare la vera risposta. Basiamo le cose su una coordinata di trama, piuttosto che sulle 4 che coprono l'intera area del frammento nello spazio texel.

Il filtro basato su mipmap utilizza immagini a bassa risoluzione. Queste immagini sono fondamentalmente una scorciatoia per il metodo perfetto, pre-calcolando come apparirebbero grandi blocchi di colori quando mescolati insieme. Pertanto, quando seleziona una mipmap inferiore, utilizza valori pre-calcolati in cui ogni texel rappresenta un'area della trama.

Il filtro anisotropico funziona approssimando il metodo perfetto (che può e dovrebbe essere accoppiato al mipmapping) prendendo fino a un numero fisso di campioni aggiuntivi. Ma come riesce a capire l'area nello spazio texel da cui recuperare, dato che ha ancora una sola coordinata di trama?

Fondamentalmente, imbroglia. Poiché gli shader di frammenti vengono eseguiti in blocchi adiacenti 2x2, è possibile calcolare la derivata di qualsiasi valore nello shader di frammento nello spazio dello schermo X e Y. Quindi utilizza queste derivate, accoppiate con le coordinate della trama effettiva, per calcolare un'approssimazione di quale sarebbe l'impronta della trama del vero frammento. E quindi esegue un numero di campioni all'interno di quest'area.

Ecco un diagramma per aiutarti a spiegarlo:

Impronta di frammento e campioni anisotropi.  FYI: se l'hai già visto, è mio.

I quadrati in bianco e nero rappresentano la nostra trama. È solo una scacchiera di 2x2 texel bianchi e neri.

Il punto arancione è la coordinata della trama per il frammento in questione. Il contorno rosso è l'impronta del frammento, che è centrato sulla coordinata della trama.

Le caselle verdi rappresentano i texel a cui potrebbe accedere un'implementazione del filtro anisotropico (i dettagli degli algoritmi di filtro anisotropico sono specifici della piattaforma, quindi posso solo spiegare l'idea generale).

Questo particolare diagramma suggerisce che un'implementazione potrebbe accedere a 4 texel. Oh sì, le caselle verdi ne coprono 7, ma la casella verde al centro potrebbe recuperare da una mipmap più piccola, recuperando così l'equivalente di 4 texel in un solo recupero. L'implementazione peserebbe ovviamente la media per quel recupero di 4 rispetto a quelli single texel.

Se il limite di filtro anisotropico fosse 2 anziché 4 (o superiore), l'implementazione selezionerebbe 2 di quei campioni per rappresentare l'impronta del frammento.


Grazie per averlo spiegato e scusate la risposta ritardata, ma ho dovuto trovare il tempo di leggerlo molto attentamente. Sento che l'unico paragrafo che non capisco completamente è quello in cui parli di shader e derivati ​​di frammenti. Cosa si ricava esattamente nello spazio dello schermo X e Y? È il valore delle coordinate della trama?
Nicola Masotti,

@NicolaMasotti: "Derivata" è un termine di calcolo. In questo caso, è il tasso di cambiamento della coordinata della trama, attraverso la superficie del triangolo, nello spazio dello schermo X o Y. Se non conosci il calcolo, non sarò in grado di spiegarlo a te in un singolo post.
Nicol Bolas,

Fortunatamente so cos'è un derivato. C'è un posto in cui posso cercare l'esatta matematica?
Nicola Masotti,

Inoltre, proporrei un paio di modifiche alla tua risposta, vale a dire " dipende da come il poligono è mappato alla trama " invece di " dipende da come la trama è mappata al poligono ". Inoltre, quando dici: " usando la copertura per ridimensionare i colori che si trovano sul bordo " intendi effettivamente " colori di peso che si trovano sul bordo "?
Nicola Masotti,

3

Alcuni punti che probabilmente già conosci, ma che voglio solo mettere in evidenza per gli altri che leggono questo. Il filtro in questo caso si riferisce al filtro passa-basso come si potrebbe ottenere da una sfocatura gaussiana o da una sfocatura della casella. Dobbiamo farlo perché stiamo prendendo alcuni media con alte frequenze in esso e rendendoli in uno spazio più piccolo. Se non lo filtrassimo, otterremmo artefatti di aliasing, che apparirebbe male. Quindi filtriamo le frequenze troppo alte per essere riprodotte accuratamente nella versione ridimensionata. (E passiamo le basse frequenze, quindi usiamo un filtro "passa basso" come una sfocatura.)

Quindi pensiamo a questo prima dal punto di vista di una sfocatura. Una sfocatura è un tipo di convoluzione. Prendiamo il kernel di convoluzione e lo moltiplichiamo per tutti i pixel in un'area, quindi li sommiamo e dividiamo per il peso. Questo ci dà l'output di un pixel. Quindi lo spostiamo e lo facciamo di nuovo per il pixel successivo, e ancora, ecc.

È molto costoso farlo in questo modo, quindi c'è un modo per imbrogliare. Alcuni kernel di convoluzione (in particolare un kernel di sfocatura gaussiana e un kernel di sfocatura casella) possono essere separati in un passaggio orizzontale e verticale. Puoi prima filtrare tutto con un solo kernel orizzontale, quindi prenderne il risultato e filtrarlo con un solo kernel verticale, e il risultato sarà identico a fare il calcolo più costoso in ogni punto. Ecco un esempio:

Originale:

Hawaii

Sfocatura orizzontale:

Hawaii sfocato in orizzontale

Orizzontale seguito da Sfocatura verticale:

Le Hawaii sono sfocate in orizzontale e poi in verticale

Quindi possiamo separare il filtro in un passaggio verticale e orizzontale. E allora? Bene, si scopre che possiamo fare la stessa cosa per le trasformazioni spaziali. Se pensi a una rotazione prospettica, in questo modo:

Hawaii ruotato attorno all'asse Y.

Può essere suddiviso in una scala X:

inserisci qui la descrizione dell'immagine

seguito da una scala di ogni colonna con un importo leggermente diverso:

Hawaii ridimensionata in X e poi proporzionalmente in Y

Quindi ora hai 2 diverse operazioni di ridimensionamento. Per ottenere il filtro corretto per questo, vorrai filtrare più pesantemente in X che in Y, e vorrai filtrare un importo diverso per ogni colonna. La prima colonna non ottiene alcun filtro perché ha le stesse dimensioni dell'originale. La seconda colonna diventa solo un po 'perché è leggermente più piccola della prima, ecc. L'ultima colonna ottiene il maggior filtraggio di qualsiasi colonna.

La parola "anisotropia" deriva dal greco "un" significato "non", "isos" che significa uguale e "tropos" che significa "direzione". Quindi significa "non uguale in tutte le direzioni". Ed è esattamente quello che vediamo: il ridimensionamento e il filtro vengono eseguiti in quantità diverse in ciascuna direzione.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.