Helfen Sie mir, die anisotrope Filterung (AF) zu verstehen.


8

In letzter Zeit habe ich über Texturfilterung gelesen, nämlich Nearest-Neighbour-Filterung, bilineare Filterung, trilineare Filterung, anisotrope Filterung, MIP-Karten, RIP-Karten und so weiter.

Aus einer hochrangigen Perspektive denke ich, dass ich diese Techniken verstehen kann, wie die Arbeit funktioniert und warum sie existieren, mit Ausnahme der anisotropen Filterung. Anisotrope Filterung macht mich verrückt.

Ich kann das Problem erkennen, dass eine Oberfläche, die sich in einem Winkel zur Kamera befindet, texturiert werden muss, aber ich verstehe nicht, wie das Abtasten von trapezförmigen Fußabdrücken dieses Problem lösen könnte (obwohl ich das Ergebnis sehen kann). Dies liegt wahrscheinlich daran, dass ich NICHT verstehe, wie der trapezförmige Fußabdruck berechnet wird und wie die beiliegenden Telexe gewichtet werden, um die Textur abzutasten.

Dieser Artikel von Nvidia verwirrt mich noch mehr, indem er Sätze wie " Wenn ein Texel trapezförmig ist " oder " Anisotrope Filterung skaliert entweder die Höhe oder die Breite einer Mipmap um ein Verhältnis relativ zur perspektivischen Verzerrung der Textur " verwendet. Trapezförmiges Texel? MIPmap skalieren? Was bedeutet das überhaupt?

Können Sie mir helfen, zu verstehen, wie AF und AF-Pegel funktionieren?

Bitte beachten Sie, dass mein Ziel NICHT darin besteht, eine OpenGL- oder DirectX-AF-Implementierung zu haben, sondern zu verstehen, wie AF aus einer übergeordneten Perspektive funktioniert.

Antworten:


10

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:

Fragment-Footprint und anisotrope Proben.  Zu Ihrer Information: Wenn Sie es schon einmal gesehen haben, gehört es mir.

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.


Vielen Dank für die Erklärung und Entschuldigung für die verspätete Antwort, aber ich musste die Zeit finden, dies sehr sorgfältig zu lesen. Ich glaube, der einzige Absatz, den ich nicht vollständig verstehe, ist der, in dem Sie über Fragment-Shader und Derivate sprechen. Was genau wird im Bildschirmraum X und Y abgeleitet? Ist es der Texturkoordinatenwert?
Nicola Masotti

@NicolaMasotti: "Derivat" ist ein Kalkülbegriff . In diesem Fall ist es die Änderungsrate der Texturkoordinate über die Oberfläche des Dreiecks im Bildschirmraum X oder Y. Wenn Sie keinen Kalkül kennen, kann ich ihn nicht erklären an Sie in einem einzigen Beitrag.
Nicol Bolas

Zum Glück weiß ich, was ein Derivat ist. Gibt es einen Ort, an dem ich nach der genauen Mathematik suchen kann?
Nicola Masotti

Außerdem würde ich ein paar Änderungen an Ihrer Antwort vorschlagen, dh " es hängt davon ab, wie das Polygon der Textur zugeordnet wird " anstelle von " es hängt davon ab, wie die Textur dem Polygon zugeordnet wird ". Wenn Sie sagen: " Verwenden der Abdeckung zum Skalieren von Farben am Rand ", meinen Sie dann tatsächlich " Gewichtsfarben am Rand "?
Nicola Masotti

3

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:

Hawaii

Horizontale Unschärfe:

Hawaii verschwamm horizontal

Horizontal gefolgt von vertikaler Unschärfe:

Hawaii verschwamm horizontal und dann vertikal

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:

Hawaii Um die Y-Achse gedreht

Es kann in eine X-Skala unterteilt werden:

Geben Sie hier die Bildbeschreibung ein

gefolgt von einer Skala jeder Spalte um einen etwas anderen Betrag:

Hawaii skalierte in X und dann proportional in Y.

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.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.