2015-02-19 4 views
7

Ich versuche im Wesentlichen zu verstehen, wie GPUs arbeiten, wenn es während der Rasterung schwebende Eckpunktkoordinaten in Festkommazahlen konvertiert.GPU: Konvertieren von Gleitpunktkoordinaten in Festkommazahlen. Wie man?

Ich lese diese excellent article, die bereits viele Dinge erklärt, aber es verwirrt mich auch. So erklärt der Artikel, dass, weil wir 32 Bit-Ganzzahlen und die Kantenfunktion verwenden, die als die folgende Form (a - b)*(c - d) - (e - f)*(g - h) sind, wir auf den Bereich [-16384,16383] beschränkt sind. Ich verstehe, wie wir zu dieser Nummer kommen. Hier sind meine Fragen:

  1. Erstens schlägt dies vor, dass Vertex-Koordinaten negativ sein können. Was ich jedoch nicht verstehe, ist, dass zu diesem Zeitpunkt Vertexkoordinaten im Rasterraum liegen und alle Dreiecke zuvor abgeschnitten worden sein sollten. Also sollte es technisch gesehen nur Eckpunktkoordinaten im Bereich [0, Bildbreite] für die x-Koordinate und [0, Bildhöhe] für die y-Koordinate geben? Warum sind Koordinaten negativ?
  2. So erklärt der Autor den Bereich ist zu begrenzt [-16384,16383]. Wenn Sie eine Breite von 2048 Pixel haben und 256 Unterpixel verwenden, müsste die Koordinate des Punktes in x 4194048 sein. Sie würden also einen Überlauf erhalten. Der Autor geht weiter und erklärt, wie sie es auf der GPU tun, um dieses Problem zu umgehen, aber ich verstehe es einfach nicht. Wenn jemand auch erklären könnte, wie es praktisch auf der GPU gemacht wird, dann wäre es großartig.
+0

Wenn Sie wirklich garantieren können, dass alle Zahlen positiv sind, können Sie unsigned Ints verwenden und ein zusätzliches Bit für Ihre Berechnungen gewinnen. Ihre Reichweite wird [-32768,32767]. Leider reicht das immer noch nicht für die 19-Bit-Nummern, die Sie in Teil 2 Ihrer Frage benötigen. –

Antwort

3
  1. Zuerst Dies legt nahe, dass Eckpunktkoordinaten negativ sein kann. Was ich jedoch nicht verstehe, ist, dass zu diesem Zeitpunkt Vertexkoordinaten im Rasterraum liegen und alle Dreiecke zuvor abgeschnitten worden sein sollten. Also sollte es technisch gesehen nur Eckpunktkoordinaten im Bereich [0, Bildbreite] für die x-Koordinate und [0, Bildhöhe] für die y-Koordinate geben? Warum sind Koordinaten negativ?

Die kurze Antwort ist, dass, während die Dreiecke abgeschnitten worden sind, haben sie auf die Darstellungsfeld nicht abgeschnitten worden ist (0,0 - Bildbreite, Bildhöhe). Stattdessen werden sie an die Clipping-Region guard-band geklammert, bei der es sich um ein größeres Rechteck handelt, das das Ansichtsfenster umgibt. Scheitelpunktkoordinaten, die sich außerhalb des Darstellungsbereichs, aber innerhalb des Schutzbereichbegrenzungsbereiches befinden, können negative Koordinaten haben.

Es gibt (mindestens) drei Arten von Dreiecks-Clipping. Der erste ist "analytisches Clipping", bei dem Sie den Schnittpunkt der Dreieckskanten mit den Kanten der Schutzbandklammerregion berechnen, wenn sie ihn überlappen, und dann das Dreieck an diesen Punkten abschneiden und den Rest in kleinere Dreiecke unterteilen , von denen jede jetzt innerhalb der Clip-Region ist. Der zweite Typ ist, wenn das Begrenzungsrechteck des Dreiecks gegen das Ansichtsfenster geclippt wird, um den Bereich der Pixel zu finden, die während der Rasterung durchlaufen werden sollen (beachten Sie, dass dies die Eckpunktkoordinaten des Dreiecks nicht ändert). Der dritte Typ ist der Pro-Pixel-Test, der in dem Artikel beschrieben wird, in dem Sie über den Bildschirm iterieren und jedes Pixel testen, um zu sehen, ob es sich innerhalb des Dreiecks befindet.

Darüber hinaus kann die Mitte des Bildschirms je nach Implementierung intern (0,0) für die Zwecke der Clipping-Berechnungen definiert werden, was bedeutet, dass alles auf der linken Seite des Bildschirms eine haben wird negative x-Koordinate.

  1. So erklärt der Autor der Bereich zu begrenzt ist [-16384,16383]. Wenn Sie eine Breite von 2048 Pixel haben und 256 Unterpixel verwenden, müsste die Koordinate des Punktes in x 4194048 sein. Sie würden also einen Überlauf erhalten.Der Autor geht weiter und erklärt, wie sie es auf der GPU tun, um dieses Problem zu umgehen, aber ich verstehe es einfach nicht. Wenn jemand auch erklären könnte, wie es praktisch auf der GPU gemacht wird, dann wäre es großartig.

Hinweis: ich kein GPU-Ingenieur bin und so ist dies nur eine High-Level-konzeptionelle Antwort:

Der Schlüsselsatz in der in dem Artikel Erklärung ist inkrementale Bewertung. Werfen Sie einen Blick auf die orient2d Gleichung:

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); 
} 

Punkte a und b sind Dreieckvertices, während Punkt c der Bildschirm Koordinaten ist. Für ein gegebenes Dreieck bleiben die Dreieckscheitelpunkte gleich, während Sie über den Bereich der Bildschirmkoordinaten iterieren, nur Punkt c Änderungen. Inkrementelle Auswertung bedeutet, dass Sie nur berechnen, was sich gegenüber der vorherigen Auswertung der Gleichung geändert hat.

Angenommen, wir werten die Gleichung einmal und erhalten ein Ergebnis w0:

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

Dann c.x um einen Betrag erhöht wird s (der pro Pixel Schritt). Der neue Wert von w0 wird sein:

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

die erste Gleichung von den zweiten Subtrahierend, erhalten wir:

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

-(b.y-a.y)*s ist ein konstanter Wert für ein gegebenes Dreieck, weil s das gleiche ist Betrag jedes Mal (ein Pixel), und a und b wie bereits erwähnt sind auch konstant. Wir können es einmal berechnen und speichern sie in einer Variablen (nennen wir es w0_step) und dann die Berechnung reduziert sich auf:

w0_new = w0 + w0step; 

Sie können dies tun, für w1 und w2, und tun auch eine ähnliche Sache für den c.y Schritt. Der Grund dafür, dass dies eine höhere Genauigkeit ermöglicht, besteht darin, dass die Pro-Pixel-Gleichung keine Festkomma-Multiplikation mehr enthält, was den Überlauf verursacht. Die GPU kann eine Hochpräzisionsberechnung einmal pro Dreieck (z. B. in 64 Bits) durchführen und dann eine niedrigere Genauigkeit pro Pixel (z. B. 32 Bits).

+0

EDIT: Entschuldigung, Sie erklären in 2, warum wir keinen Überlauf haben, und ich weiß das wirklich zu schätzen, also werde ich Ihre Antwort akzeptieren, obwohl ich idealerweise eine Antwort gewünscht hätte, die auch erklärt, wie Koordinaten zum festen Punkt konvertiert werden. Trotzdem werde ich es akzeptieren. Danke nochmal für deine Mühe. – user18490