Perché l'accesso alle trame è molto più lento quando si calcola la coordinata della trama nello shader di frammento?


11

Quando si usano le trame in GLSL, è meglio calcolare le coordinate finali della trama nello shader di vertice e consegnarle allo shader di frammento usando varyings. Esempio con un semplice capovolgimento nella coordinata y:

// Vertex shader
attribute vec2 texture;
varying highp vec2 texCoord;
// ...
void main() {
    texCoord = vec2(texture.x, 1.0-texture.y);
    // ...
}

// Fragment shader
varying highp vec2 textureCoordinates;
uniform sampler2D tex;
// ...
void main() {
    highp vec4 texColor = texture2D(tex, texCoord);
    // ...
}

Se il capovolgimento della coordinata y, o un'operazione ancora più semplice come l'aggiunta vec2(0.5)alla coordinata della trama, viene eseguita nello shader di frammenti, l'accesso alla trama è molto più lento. Perché?


Come nota, ad esempio la fusione di due trame, usando una somma ponderata di esse, è molto più economica in termini di tempo e deve anche essere eseguita per ogni pixel, quindi il calcolo della coordinata della trama stessa non sembra essere così costoso.


1
La mia ipotesi sarebbe che se i cordoni UV sono calcolati in VS, l'unità texture può iniziare a precaricarli mentre il PS sta avviando. Se sono calcolati nel PS, l'unità texture deve prima aspettare.
RichieSams,

2
In seguito, questa viene chiamata "lettura della trama dipendente", nel caso in cui aiuti la tua ricerca.
Alan Wolfe,

Hai delle misure che mostrano la differenza perf? In realtà non mi aspetto che ci sia molta differenza; la latenza di recupero trama dovrebbe inondare alcune operazioni ALU. A proposito, le letture di texture dipendenti sono dove ci sono due (o più) letture di texture, con le coordinate per la seconda che dipendono dall'output della prima. Questi sono più lenti a causa del rigoroso ordinamento richiesto tra le due letture della trama.
Nathan Reed,

Bene, qualsiasi operazione eseguita nello shader di frammento sarà più costosa che nello shader di vertice. Ogni triangolo accetta 3 invocazioni di uno shader di vertice, ma potrebbe richiedere ordini di grandezza maggiori invocazioni dello shader di frammenti, a seconda delle dimensioni dello schermo.
glampert

@NathanReed Non credo che devi limitare le "letture di trama dipendenti" solo a quelle che provengono da un accesso alla trama precedente. Probabilmente includerei anche tutte le coordinate calcolate nel frag shader, al contrario di quelle che possono essere determinate semplicemente dall'interpolazione lineare (bene, iperbolica con prospettiva) degli attributi del vertice.
Simon F,

Risposte:


11

Quello di cui stai parlando è comunemente chiamato "letture di texture dipendenti" nella comunità di sviluppo mobile. È un dettaglio dell'implementazione di determinati hardware e quindi dipende davvero dalla GPU se ha o meno implicazioni sulle prestazioni. In genere è qualcosa che vedi allevato per GPU PowerVR nell'hardware Apple, poiché è stato esplicitamente menzionato sia in Imagination che in Appledocumentazione. Se ricordo bene, il problema derivava fondamentalmente dall'hardware della GPU che avrebbe iniziato a precaricare le trame prima ancora che lo shader di frammenti iniziasse a funzionare, in modo che potesse fare un lavoro migliore nel nascondere la latenza. I documenti che ho collegato menzionano che non è più un problema sull'hardware Series6, quindi almeno sull'hardware Apple più recente non è qualcosa di cui devi preoccuparti. Onestamente non sono sicuro di altre GPU mobili, dal momento che non è la mia area di competenza. Dovresti provare a consultare la loro documentazione per scoprirlo di sicuro.

Se decidi di effettuare alcune ricerche su Google su questo problema, tieni presente che probabilmente troverai del materiale più vecchio che parla di recuperi di texture dipendenti su hardware desktop meno recente. Fondamentale nei primi tempi degli shader pixel / frammento, il termine "recupero di trama dipendente" si riferiva all'uso di un indirizzo UV che si basava su un precedente recupero di trama. L'esempio classico era il rendering della mappa di ambiente mappato in rilievo, in cui si voleva utilizzare un vettore di riflessione basato sulla mappa normale per campionare la mappa di ambiente. Su questo vecchio hardware c'erano alcune importanti implicazioni sulle prestazioni e penso che non fosse nemmeno supportato su alcune GPU molto vecchie. Con le moderne GPU l'hardware e lo shader ISA sono molto più generalizzati, quindi la situazione delle prestazioni è molto più complicata.


A proposito: l'ho sperimentato su un iPad 3. Quindi forse questo è in realtà specifico dell'hardware.
Nero,
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.