2015-02-19 25 views
7

Sto essenzialmente cercando di capire come funzionano le GPU quando si converte le coordinate dei vertici mobili in numeri fissi durante la rasterizzazione.GPU: conversione delle coordinate del vertice a virgola mobile in virgola fissa. Come?

Ho letto questo excellent article che spiega già molte cose, ma mi confonde anche. Quindi l'articolo spiega che, poiché utilizziamo numeri interi a 32 bit e la funzione edge, come il seguente modulo (a - b)*(c - d) - (e - f)*(g - h), siamo limitati all'intervallo [-16384,16383]. Capisco come arriveremo a questo numero. Ecco le mie domande:

  1. In primo luogo, questo suggerisce che le coordinate del vertice possono essere negative. Tuttavia quello che non capisco è che tecnicamente in quel momento le coordinate del vertice sono nello spazio raster e tutti i triangoli dovrebbero essere stati prima tagliati. Quindi tecnicamente ci dovrebbero essere solo le coordinate del vertice nell'intervallo [0, larghezza immagine] per la coordinata x e [0, altezza immagine] per la coordinata y? Allora perché le coordinate sono negative?
  2. Quindi l'autore spiega che l'intervallo è troppo limitato [-16384,16383]. In effetti se hai una larghezza di 2048 pixel e usi 256 sottopixel, allora la coordinata del punto in x dovrebbe essere 4194048. Così si otterrebbe un overflow. L'autore continua e spiega come lo fanno sulla GPU per ovviare a questo problema, ma semplicemente non capisco. Se qualcuno potesse anche spiegare come è praticamente fatto sulla GPU, sarebbe fantastico.
+0

Se si è veramente in grado di garantire che tutti i numeri siano positivi, è possibile utilizzare valori non firmati e ottenere un ulteriore valore per i calcoli. Il tuo intervallo diventa [-32768,32767]. Sfortunatamente non è ancora abbastanza per i numeri a 19 bit richiesti nella seconda parte della tua domanda. –

risposta

3
  1. Innanzitutto, questo suggerisce che le coordinate dei vertici possono essere negativi. Tuttavia quello che non capisco è che tecnicamente in quel momento le coordinate del vertice sono nello spazio raster e tutti i triangoli dovrebbero essere stati prima tagliati. Quindi tecnicamente ci dovrebbero essere solo le coordinate del vertice nell'intervallo [0, larghezza immagine] per la coordinata x e [0, altezza immagine] per la coordinata y? Allora perché le coordinate sono negative?

La risposta breve è che, mentre i triangoli sono stati tagliati, non sono stati tagliati alla finestra (0,0 - larghezza dell'immagine, altezza dell'immagine). Invece, vengono ritagliate nell'area di ritaglio guard-band, che è un rettangolo più grande che circonda il viewport. Le coordinate del vertice che si trovano al di fuori del viewport ma all'interno dell'area di clipping della banda di guardia possono avere coordinate negative.

Ci sono (almeno) tre tipi di clipping triangolare. Il primo è "ritaglio analitico", ovvero quando si calcola l'intersezione dei bordi del triangolo con i bordi dell'area della clip della banda di guardia se si sovrappongono, quindi si taglia il triangolo in quei punti e si suddivide il resto in triangoli più piccoli , ognuno dei quali è ora all'interno della regione della clip. Il secondo tipo è quando il riquadro di delimitazione del triangolo viene agganciato alla finestra per trovare l'intervallo di pixel da iterare durante la rasterizzazione (notare che questo non cambia le coordinate del vertice del triangolo). Il terzo tipo è il test per pixel descritto nell'articolo in cui si sta iterando attraverso lo schermo e si verifica ogni pixel per vedere se si trova all'interno del triangolo.

Inoltre, a seconda dell'implementazione, il centro dello schermo può essere definito come (0,0) internamente ai fini dei calcoli di ritaglio, il che significa che qualsiasi cosa sul lato sinistro dello schermo avrà un coordinata x negativa.

  1. Quindi l'autore spiega che l'intervallo è troppo limitato [-16384,16383]. In effetti se hai una larghezza di 2048 pixel e usi 256 sottopixel, allora la coordinata del punto in x dovrebbe essere 4194048. Così si otterrebbe un overflow.L'autore continua e spiega come lo fanno sulla GPU per ovviare a questo problema, ma semplicemente non capisco. Se qualcuno potesse anche spiegare come è praticamente fatto sulla GPU, sarebbe fantastico.

Nota: io non sono un ingegnere GPU e così questo è solo un alto livello di risposta concettuale:

La frase chiave nella spiegazione data in questo articolo è valutazione incrementale. Date un'occhiata a l'equazione orient2d:

int orient2d(const Point2D& a, const Point2D& b, const Point2D& c) 
{ 
    return (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x); 
} 

Punti a e b sono vertici del triangolo, mentre il punto c è il co-ordinata schermo. Per un triangolo dato, i vertici del triangolo rimarranno gli stessi mentre si scorre sull'intervallo di coordinate dello schermo, solo le variazioni di punto c. Valutazione incrementale significa che si calcola ciò che è cambiato rispetto alla volta precedente in cui è stata valutata l'equazione.

Supponiamo di calcolare l'equazione una volta e ottenere un risultato w0:

w0 = (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x-a.x); 

Poi c.x ottiene incrementato di una quantità s (il passo per pixel). Il nuovo valore di w0 sarà:

w0_new = (b.x-a.x)*(c.y-a.y) - (b.y-a.y)*(c.x+s-a.x); 

Sottraendo la prima equazione dalla seconda, otteniamo:

w0_new - w0 = -(b.y-a.y)*s; 

-(b.y-a.y)*s è un valore costante per un dato triangolo, perché s è lo stesso importo ogni volta (un pixel) e a e b come già menzionato sono anche costanti. Possiamo calcolare una volta e memorizzarlo in una variabile (chiamarlo w0_step) e quindi il calcolo si riduce a:

w0_new = w0 + w0step; 

Si può fare questo per w1 e w2, e anche fare una cosa simile per il passo c.y. La ragione per cui ciò consente una maggiore precisione è che l'equazione per pixel non contiene più un multiplo a virgola fissa, che è ciò che causa l'overflow. La GPU può eseguire un calcolo ad alta precisione una volta per triangolo (ad esempio in 64 bit) e quindi eseguire una precisione inferiore per pixel (ad esempio 32 bit).

+0

EDIT: scusa ci spieghi in 2 perché non abbiamo overflow e lo apprezzo molto, quindi accetterò la tua risposta anche se avrei preferito una risposta che spiegasse anche "COME" sono le coordinate convertite in punto fisso. Tuttavia lo accetterò. Grazie ancora per il tuo impegno. – user18490