Um die Natur der anisotropen Filterung zu verstehen, müssen Sie genau wissen, was Texturabbildung wirklich bedeutet.
Der Begriff "Texturabbildung" bedeutet, Positionen auf einem Objekt Positionen in einer Textur zuzuweisen. Dadurch kann der Rasterizer / Shader für jede Position auf dem Objekt die entsprechenden Daten aus der Textur abrufen. Die herkömmliche Methode hierfür besteht darin, jedem Scheitelpunkt eines Objekts eine Texturkoordinate zuzuweisen, die diese Position direkt einer Position in der Textur zuordnet. Der Rasterer interpoliert diese Texturkoordinate über die Flächen der verschiedenen Dreiecke, um die Texturkoordinate zu erzeugen, die zum Abrufen der Farbe aus der Textur verwendet wird.
Lassen Sie uns nun über den Prozess der Rasterung nachdenken. Wie funktioniert das? Es nimmt ein Dreieck und zerlegt es in pixelgroße Blöcke, die wir "Fragmente" nennen werden. Diese pixelgroßen Blöcke sind nun relativ zum Bildschirm pixelgroß.
Diese Fragmente sind jedoch im Verhältnis zur Textur nicht pixelgroß. Stellen Sie sich vor, unser Rasterizer hat für jede Ecke des Fragments eine Texturkoordinate generiert. Stellen Sie sich nun vor, Sie zeichnen diese 4 Ecken nicht im Bildschirmbereich, sondern im Texturbereich . Welche Form wäre das?
Nun, das hängt von den Texturkoordinaten ab. Das heißt, es hängt davon ab, wie die Textur dem Polygon zugeordnet wird. Für ein bestimmtes Fragment kann es sich um ein achsenausgerichtetes Quadrat handeln. Es kann sich um ein nicht achsenausgerichtetes Quadrat handeln. Es könnte ein Rechteck sein. Es könnte ein Trapez sein. Es könnte so ziemlich jede vierseitige Figur sein (oder zumindest konvexe).
Wenn Sie den Texturzugriff korrekt ausführen, können Sie die Texturfarbe für ein Fragment ermitteln, indem Sie herausfinden, um welches Rechteck es sich handelt. Rufen Sie dann jedes Texel aus der Textur in diesem Rechteck ab (verwenden Sie die Abdeckung, um die Farben am Rand zu skalieren). Dann mitteln Sie sie alle zusammen. Das wäre eine perfekte Texturabbildung.
Es wäre auch außerordentlich langsam .
Im Interesse der Leistung versuchen wir stattdessen, die tatsächliche Antwort zu approximieren. Wir basieren auf einer Texturkoordinate und nicht auf der 4, die den gesamten Bereich des Fragments im Texelraum abdeckt.
Bei der Mipmap-basierten Filterung werden Bilder mit niedrigerer Auflösung verwendet. Diese Bilder sind im Grunde eine Abkürzung für die perfekte Methode, indem vorab berechnet wird, wie große Farbblöcke aussehen würden, wenn sie zusammengemischt werden. Wenn also eine niedrigere Mipmap ausgewählt wird, werden vorberechnete Werte verwendet, wobei jedes Texel einen Bereich der Textur darstellt.
Die anisotrope Filterung approximiert die perfekte Methode (die mit Mipmapping gekoppelt werden kann und sollte), indem bis zu einer festen Anzahl zusätzlicher Proben entnommen wird. Aber wie wird der Bereich im Texelraum ermittelt, aus dem abgerufen werden soll, da immer noch nur eine Texturkoordinate angegeben ist?
Grundsätzlich betrügt es. Da Fragment-Shader in 2x2 benachbarten Blöcken ausgeführt werden, ist es möglich, die Ableitung eines beliebigen Werts im Fragment-Shader im Bildschirmraum X und Y zu berechnen. Anschließend werden diese Ableitungen in Verbindung mit der tatsächlichen Texturkoordinate verwendet, um eine Approximation von zu berechnen Was wäre der Textur-Footprint des wahren Fragments? Und dann führt es eine Reihe von Samples in diesem Bereich durch.
Hier ist ein Diagramm, um es zu erklären:
Die schwarz-weißen Quadrate repräsentieren unsere Textur. Es ist nur ein Schachbrett aus 2x2 weißen und schwarzen Texeln.
Der orangefarbene Punkt ist die Texturkoordinate für das betreffende Fragment. Der rote Umriss ist der Footprint des Fragments, der auf der Texturkoordinate zentriert ist.
Die grünen Felder stellt die Texeln , dass eine anisotrope Filterung Implementierung könnte Zugang (die Details der anisotropen Filteralgorithmen sind plattformspezifisch, so kann ich nur die allgemeine Idee erklären).
Dieses spezielle Diagramm legt nahe, dass eine Implementierung möglicherweise auf 4 Texel zugreift. Oh ja, die grünen Kästchen decken 7 davon ab, aber das grüne Kästchen in der Mitte könnte von einer kleineren Mipmap abgerufen werden, wodurch das Äquivalent von 4 Texeln in einem Abruf abgerufen wird. Die Implementierung würde natürlich den Durchschnitt für diesen Abruf im Vergleich zu den einzelnen Texelwerten um 4 gewichten.
Wenn die anisotrope Filtergrenze 2 statt 4 (oder höher) wäre, würde die Implementierung 2 dieser Proben auswählen, um den Fußabdruck des Fragments darzustellen.
Ein paar Punkte, die Sie wahrscheinlich bereits kennen, die ich aber nur für andere veröffentlichen möchte, die dies lesen. Filterung bezieht sich in diesem Fall auf Tiefpassfilterung, wie Sie sie möglicherweise von einer Gaußschen Unschärfe oder einer Box-Unschärfe erhalten. Wir müssen dies tun, weil wir einige Medien mit hohen Frequenzen aufnehmen und auf kleinerem Raum rendern. Wenn wir es nicht filtern würden, würden wir Aliasing-Artefakte erhalten, die schlecht aussehen würden. Daher filtern wir die Frequenzen heraus, die zu hoch sind, um in der skalierten Version genau wiedergegeben zu werden. (Und wir lassen die tiefen Frequenzen durch, also verwenden wir einen "Tiefpass" -Filter wie eine Unschärfe.)
Denken wir also zuerst unter dem Gesichtspunkt einer Unschärfe darüber nach. Eine Unschärfe ist eine Art Faltung. Wir nehmen den Faltungskern und multiplizieren ihn mit allen Pixeln in einem Bereich. Dann addieren wir sie und dividieren durch das Gewicht. Das gibt uns die Ausgabe von einem Pixel. Dann verschieben wir es und machen es für das nächste Pixel noch einmal usw.
Es ist wirklich teuer, es so zu machen, also gibt es eine Möglichkeit zu betrügen. Einige Faltungskerne (insbesondere ein Gaußscher Unschärfekern und ein Box-Unschärfekern) können in einen horizontalen und einen vertikalen Durchgang unterteilt werden. Sie können alles zuerst mit nur einem horizontalen Kernel filtern, dann das Ergebnis daraus nehmen und es mit nur einem vertikalen Kernel filtern. Das Ergebnis ist identisch mit der teureren Berechnung an jedem Punkt. Hier ist ein Beispiel:
Original:
Horizontale Unschärfe:
Horizontal gefolgt von vertikaler Unschärfe:
So können wir die Filterung in einen vertikalen und einen horizontalen Durchgang unterteilen. Na und? Nun, es stellt sich heraus, dass wir dasselbe für räumliche Transformationen tun können. Wenn Sie über eine perspektivische Rotation nachdenken, gehen Sie wie folgt vor:
Es kann in eine X-Skala unterteilt werden:
gefolgt von einer Skala jeder Spalte um einen etwas anderen Betrag:
Jetzt haben Sie zwei verschiedene Skalierungsoperationen. Um die Filterung zu korrigieren, sollten Sie in X stärker filtern als in Y, und Sie möchten für jede Spalte nach einem anderen Betrag filtern. Die erste Spalte wird nicht gefiltert, da sie dieselbe Größe wie das Original hat. Die zweite Spalte wird nur wenig, weil sie nur geringfügig kleiner als die erste usw. ist. Die letzte Spalte wird von allen Spalten am meisten gefiltert.
Das Wort "Anisotropie" kommt aus dem Griechischen "und" bedeutet "nicht", "isos" bedeutet gleich und "tropos" bedeutet "Richtung". Es bedeutet also "nicht in alle Richtungen gleich". Und genau das sehen wir - die Skalierung und die Filterung erfolgen in jeder Richtung in unterschiedlichen Mengen.
quelle