Come vengono calcolati i livelli di mipmap in Metal?


14

La mia domanda riguarda in particolare Metal, poiché non so se la risposta cambierebbe per un'altra API.

Ciò che credo di aver capito finora è questo:

  • Una trama mipmapped ha pre-calcolato i "livelli di dettaglio", in cui i livelli più bassi di dettaglio vengono creati effettuando il downsampling della trama originale in modo significativo.

  • I livelli di mipmap sono indicati in ordine decrescente di dettaglio, dove livello 0è la trama originale e livelli più alti ne riducono la potenza di due.

  • La maggior parte delle GPU implementano il filtro trilineare, che seleziona due livelli mipmap adiacenti per ciascun campione, campioni da ciascun livello utilizzando il filtro bilineare e quindi fonde linearmente quei campioni.

Quello che non capisco bene è come vengono selezionati questi livelli mipmap. Nella documentazione per la libreria standard di Metal, vedo che è possibile prelevare campioni, con o senza specificare un'istanza di un lod_optionstipo. Suppongo che questo argomento cambierà la modalità di selezione dei livelli di mipmap e che apparentemente ci sono tre tipi di lod_optionstrame 2D:

  • bias(float value)
  • level(float lod)
  • gradient2d(float2 dPdx, float2 dPdy)

Sfortunatamente, la documentazione non si preoccupa di spiegare cosa fanno queste opzioni. Posso indovinare che bias()distorce alcuni livelli di dettaglio scelti automaticamente, ma allora cosa significa pregiudizio value? Su quale scala opera? Analogamente, come è il loddi level()traduce in livelli discreti mipmap? E, operando nel presupposto che gradient2d()utilizza il gradiente della coordinata della trama, come usa quel gradiente per selezionare il livello di mipmap?

Ancora più importante, se lod_optionsometto, come vengono selezionati i livelli di mipmap? Ciò differisce in base al tipo di funzione eseguita?

E, se l'operazione predefinita specificata no-lod-options della sample()funzione è fare qualcosa di simile gradient2D()(almeno in uno shader di frammenti), utilizza derivati ​​dello spazio dello schermo semplici o funziona direttamente con rasterizzatore e coordinate di trama interpolate calcolare un gradiente preciso?

E infine, quanto è coerente questo comportamento da dispositivo a dispositivo? Un vecchio articolo (vecchio come in DirectX 9) che ho letto si riferiva a una selezione mipmap complessa specifica del dispositivo, ma non so se la selezione mipmap sia meglio definita su architetture più recenti.

Risposte:


17

La selezione di mip è oggi abbastanza ben standardizzata su tutti i dispositivi, ad eccezione di alcuni dettagli nitidi del filtro anisotropico, che spetta ancora ai singoli produttori di GPU definire (e i suoi dettagli precisi non sono generalmente documentati pubblicamente).

Un buon posto per leggere in dettaglio la selezione di mip è nelle specifiche OpenGL, sezione 8.14, "Minimizzazione delle trame" . Immagino che funzioni allo stesso modo in Metal. (Apple avrebbe potuto cambiare qualcosa, considerando che creavano sia l'hardware che l'API ... ma dubito che lo abbiano fatto.) Lo riassumerò qui.

La selezione mip predefinita (non utilizzando nessuno dei lod_optionsmodificatori) utilizza i gradienti dello spazio dello schermo delle coordinate della trama per selezionare i livelli di mip. In sostanza, cerca di scegliere i livelli di mip che producono il più vicino possibile a una mappatura 1: 1 di texel su pixel. Ad esempio, se i gradienti hanno una lunghezza di 4 texel per pixel, sceglierebbe il livello mip 2 (che è 1/4 della dimensione del livello 0 e quindi ti dà 1 texel mipped per pixel).

Con il filtro trilineare, poiché di solito non atterri su una mappatura 1: 1 esatta , seleziona i due livelli più vicini e si interpola linearmente tra loro, in modo da avere una transizione graduale tra i livelli di mip mentre la telecamera o gli oggetti nella scena si muovono in giro.

λλλλ=2.8

λlog2(1/4)=-2

Ora, per quanto riguarda le opzioni di modifica:

  • biasλ
  • levelλλlod
  • gradient2dti consente di inserire i tuoi vettori di gradiente, che sostituiscono i gradienti di spazio-schermo impliciti delle coordinate della trama. Il resto del processo di selezione e campionamento del mip procede normalmente, ma con i gradienti modificati. Ciò consente di personalizzare il filtro anisotropico.

In altri tipi di shader oltre ai framment shader, non esiste la nozione di "gradienti dello spazio dello schermo", quindi le ultime due operazioni sono in genere le uniche consentite: qualsiasi operazione che tenti di utilizzare gradienti impliciti darebbe un errore di compilazione. Non sono sicuro che sia così che fa Metal, ma è quello che mi aspetterei da lavorare con altre API.

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.