Archiv verlassen und diese Seite im Standarddesign anzeigen : Besser als trilinear: Mit 4x4-Filter single pass, single clock möglich, oder nicht?
http://www.aths.net/files/td1.gif
Eine Grafik, um ein konkretes Beispiel zu haben. Jedes Kästchen ist ein Texel, rot die Sampleposition eingetragen. In der hoch aufgelösten MIP-Map werden die beiden umgebenden Texel (mit einem 2x2-Kernel von dem 2 Texel Null-gewichtet sind) gefiltert, dann kommt die niedrig aufgelöste MIP-Map zum Zuge, die sich aus einer 2x2-Vorfilterung ergibt.
http://www.aths.net/files/td2.gif
Hier wird eine Art "Verschiebungsfehler" deutlich: Der neue Kernel ist zwar noch immer um das Sample zentriert. Aber die Texel, die zur Farbe beitragen, liegen hier eher links als rechts. Uneinsichtigerweise beeinflussen in diesem Beispiel die Texel links das Sample mehr, als jene rechts — ein Effekt, der aus der festen Vorfilterung der MIP-Map resultiert.
http://www.aths.net/files/td.gif
Nun sieht man natürlich, dass mit einem 4x4-Filter single pass, single clock trilineare Filterung möglich ist. (Kosten: Verdoppelung des Texture-Caches, Vervierfachung der internen Bandbreite zum Cache, zusätzliche LERPs, mehr Logik für die Gewichtungs-Matrix, mehr Logik für die Matrizenmultiplikation, eine tiefere Pipeline um die neuen Latenzen zu verstecken.)
Die Frage ist nun, ob mit einem 4x4-Filter auch bessere Filterung möglich ist. Idealerweise sollte ja der Kernel um das Sample zentriert werden. Dazu hätte man eine 4x4-Fläche, wozu aber ein 5x5-Filter notwendig wäre, damit dieser Kernel frei positionierbar ist.
Oder reicht es, einen 3x3-Kernel um das Sample zu legen, um besser als trilinear zu filtern?
Wenn ja, wie berechnet man die Gewichtungs-Matrix? Neben der konkreten Samplepositions-Fraktionen sollte auch der LOD-Fraktionsteile eine wichtige Rolle spielen; aber wie bringt man das zusammen?
Mein Ansatz geht so: Ein bilinearer Filter hat eine Kernel-Breite von 1 Texel. Um eine MIP-Stufe tiefer zu gehen (Richtung höherer Auflösung) braucht man eine Kernel-Breite von 2 Texeln, sprich einen 3x3-Filter. Wenn man nun eine Filterkernel-Breite von 3 hat (wozu ein 4x4-Filter nötig ist) kriegt man "krumme" MIP-Map-LODs raus. U. U. müsste man dieses LOD anpassen, und dann eine Matrix bilden, die die Interpolation zwischen einem Sample mit 1,5 Texeln Kernelbreite und einem Sample mit 3 Texeln Kernelbreite nachstellt.
Andererseits, könnte man nicht schon mit einem 3x3-Filter besser als herkömmlich trilinear filtern? Der zusätzliche Hardware-Aufwand hielte sich dann sehr im Rahmen.
zeckensack
2003-11-03, 17:54:35
Original geschrieben von aths
http://www.aths.net/files/td2.gif
Hier wird eine Art "Verschiebungsfehler" deutlich: Der neue Kernel ist zwar noch immer um das Sample zentriert. Aber die Texel, die zur Farbe beitragen, liegen hier eher links als rechts. Uneinsichtigerweise beeinflussen in diesem Beispiel die Texel links das Sample mehr, als jene rechts — ein Effekt, der aus der festen Vorfilterung der MIP-Map resultiert.Ich habe keine Ahnung, wovon du sprichst :|
Dein Bildchen zeigt jedenfalls nichts dergleichen, und auch sonst will sich mir die Begründung nicht erschließen.
PS: längeres Posting zum Thema folgt.
Original geschrieben von zeckensack
Ich habe keine Ahnung, wovon du sprichst :|
Dein Bildchen zeigt jedenfalls nichts dergleichen, und auch sonst will sich mir die Begründung nicht erschließen.
PS: längeres Posting zum Thema folgt. Trotzdem schon mal, was da gemeint ist:
Die beiden "großen" Texel links setzen sich ja (wegen der MIP-Map-Vorfilterung) aus einem 2x2 Texelblock zusammen. Damit fließen auch Texel ein, die sehr weit weg von der Sampleposition sind. Diese "weiten" Texel fließen nur schwach ein, aber immerhin. Rechts gibt es Texel (nicht mehr im Bild) die genauso weit weg sind, aber die nicht zur Sample-Farbe beitragen.
Auf dein längeres Posting bin ich schon gespannt :)
zeckensack
2003-11-03, 18:29:24
Klassisch Triliner
lerp(w,a,b):=w*a+(1-w)*a für w in [0...1]
s[0;0]:=
lerp(lod_frac,
(lerp(wx,
lerp(wy,mip0[-0.5;-0.5],mip0[-0.5;+0.5]),
lerp(wy,mip0[+0.5;-0.5],mip0[+0.5;+0.5])
),
(lerp(wx,
lerp(wy,mip1[-1.0;-1.0],mip1[-1.0;+1.0]),
lerp(wy,mip1[+1.0;-1.0],mip1[+1.0;+1.0])
)
)
Klar? :)
mip1[-1.0;-1.0]=
0.25*(mip0[-0.5;-0.5]+mip0[-0.5;-1.5]+
mip0[-1.5;-0.5]+mip0[-1.5;-1.5]
)
mip1[+1.0;-1.0]=
0.25*(mip0[+0.5;-0.5]+mip0[+0.5;-1.5]+
mip0[+1.5;-0.5]+mip0[+1.5;-1.5]
)
mip1[+1.0;+1.0]=
0.25*(mip0[+0.5;+0.5]+mip0[+0.5;+1.5]+
mip0[+1.5;+0.5]+mip0[+1.5;+1.5]
)
mip1[-1.0;+1.0]=
0.25*(mip0[-0.5;+0.5]+mip0[-0.5;+1.5]+
mip0[-1.5;+0.5]+mip0[-1.5;+1.5]
)
So. Das ganze komplett einzusetzen würde jetzt in eine ganze Menge Text ausarten, aber:
1)Nur die zweite Hälfte des ursprünglichen Lerps ist betroffen.
2)Die Gewichtung der 2x2-Blöcke innerhalb der 'zweiten Mipmap-Stufe' ist konstant bei jeweils 0,25. Man braucht also keine zusätzlichen Lerps.
3)Der Kernel kann weiterhin exakt 4x4 groß bleiben. Bei einem 5x5-Kernel hätte man immer an zwei Kanten Texel mit 0-Gewichten, und die braucht man nicht.
Liegt ein Missverständnis vor? Wie man mit 4x4 "normal trilinear" filtern kann, ist klar. Die Frage ist, ob es besser geht, bzw. ob dafür sogar ein 3x3-Filter ausreicht. (Oder habe ich deinen Code falsch verstanden? http://www.aths.net/files/smilies/bescheuert.gif)
zeckensack
2003-11-03, 18:47:13
Und jetzt 'richtiges' Trilinear ;)
Idee:
Die äußeren 12 Texel (4²-2²) dienen der Frequenzreduktion. Bei Tendenz zu Verkleinerung müssen diese stärker gewichtet werden, bis hin zu Gleichstand mit den inneren 4 Texeln.
Oder anders gesagt:
Wenn ein bilinearer Filter die maximale Schärfe bringen kann, dann wird der Kranz komplett mit 0 gewichtet, die inneren vier mit lerps verrechnet.
Wenn die Frequenz weiter reduziert werden muß, kommt wieder lod_frac ins Spiel.
kranz--:=(mip0[-1.5;-1.5]+mip0[-1.5;-0.5]+mip0[-0.5;-1.5])/3
kranz-+:=(mip0[-1.5;+1.5]+mip0[-1.5;+0.5]+mip0[-0.5;+1.5])/3
kranz+-:=(mip0[+1.5;-1.5]+mip0[+1.5;-0.5]+mip0[+0.5;-1.5])/3
kranz++:=(mip0[+1.5;+1.5]+mip0[+1.5;+0.5]+mip0[+0.5;+1.5])/3
s(0;0):=
lerp(wx,
lerp(wy,
lerp(lod_frac,mip0[-0.5;-0.5],kranz--),
lerp(lod_frac,mip0[-0.5;+0.5],kranz-+)
),
lerp(wy,
lerp(lod_frac,mip0[+0.5;-0.5],kranz+-),
lerp(lod_frac,mip0[+0.5;+0.5],kranz++)
)
)
Ich hoffe mal, daß das alles so stimmt =)
zeckensack
2003-11-03, 18:48:50
Original geschrieben von aths
Liegt ein Missverständnis vor? Wie man mit 4x4 "normal trilinear" filtern kann, ist klar. Die Frage ist, ob es besser geht, bzw. ob dafür sogar ein 3x3-Filter ausreicht. (Oder habe ich deinen Code falsch verstanden? http://www.aths.net/files/smilies/bescheuert.gif) Siehe oben :schlag:
3x3-Kernel bringen Maximalfrequenzstufen, die nicht auf Zweierpotenzen liegen. IMO keine g00te Idee :D
Original geschrieben von zeckensack
Siehe oben :schlag:
3x3-Kernel bringen Maximalfrequenzstufen, die nicht auf Zweierpotenzen liegen. IMO keine g00te Idee :D 3x3-Filter != 3x3-Kernel. Der 3x3-Filter soll ja nur einen 2x2-Kernel applizieren. BTW sagen mir deine Worte mehr, als dein Code.
zeckensack
2003-11-03, 19:07:46
Original geschrieben von aths
3x3-Filter != 3x3-Kernel. Der 3x3-Filter soll ja nur einen 2x2-Kernel applizieren. BTW sagen mir deine Worte mehr, als dein Code. äthselchen,
ein paar Sachen muß man einfach voraussetzen. Eben die Gewichte für die lerps. Die gibt's auch aktuell in Hardware.
lod_frac ist die Position 'zwischen' Miplevel n und Miplevel n+1.
wx ist die Nachkommastelle der X-Position des Sampling-Punkts.
wy dito.
Alle diese Werte sind [0...1). Dh inklusive 0, exklusive 1.
Wenn wx 1.0 wäre, wäre das äquivalent zu wx=0 und um eins verschobener Sample-Position.
Das gleiche gilt auch für deinen 3x3-Kernel. Wenn du immer nur 2x2 Texel wirklich verrechnest, dann brauchst du auch nur einen 2x2-Kernel, den du entsprechend öfter verschiebst.
zeckilein,
vielleicht müssten wir einige Begrifflichkeiten untereinander klären, denn im Moment habe ich das Gefühl, dass wir entweder aneinander vorbei reden, oder dass ich überhaupt nichts vom dem raffe, was du sagst... (in diesem Falle bitte langsam sprechen.)
Normales BF filtert 4 Texel aus einem 2x2-Block. Um das Gewicht jeden Texels zu bestimmen, kann man sich die Texel entweder als "Nadelspitzen" vorstellen, die linear verbunden werden, oder man kann sie sich als farbige Quadrate vorstellen, worüber der Kernel gelegt wird.
Bei BF hat der Kernel die Länge und Breite von 1 Texel (1x1-Kernel), da der Kernel frei verschiebbar ist, also fast immer 4 Texel teilweise vom Kernel verdeckt sind, braucht's einen 2x2-Filter.
Gehst du soweit mit?
zeckensack
2003-11-03, 19:37:33
athsimausi,
Kantenlänge? Okay, das war dann ein Missverständnis. "3x3 Kernel" klingt für mich nach 9 Abgriffen, nicht nach 16.
Die Visualisierung mit den Rechtecken ist nicht unbedingt hilfreich, weil sie unendlich fein aufgelöste Abtastung suggeriert. Ich habe mal was angehängt. Für die Gewichtung habe ich Grün genommen (s/w war schon vergriffen).
Original geschrieben von zeckensack
athsimausi,
Kantenlänge? Okay, das war dann ein Missverständnis. "3x3 Kernel" klingt für mich nach 9 Abgriffen, nicht nach 16.
Die Visualisierung mit den Rechtecken ist nicht unbedingt hilfreich, weil sie unendlich fein aufgelöste Abtastung suggeriert. Ich habe mal was angehängt. Für die Gewichtung habe ich Grün genommen (s/w war schon vergriffen). Zeckischnucki,
da ich leider gerne alles selbst herleite ist es wahrscheinlich, dass ich Begriffe auf ungebräuchliche Weise verwende.
Allerdings weiß ich noch nicht, wie du das mit der unendlich feinen Auflösung meinst - sprichst du den endlich aufgelösten Fraktionsteil an?
Das mit dem 3x3-Körnel würde ich gerne erst mal noch zurück stellen.
Wenn man mit einem 2x2-Kernel filtert (und dazu 9 Texel braucht) kann man ja immer ein MIP-Level "weiter vorne" nehmen. Man generiert sich quasi die eigentlich gebrauchte MIP-Map selbst, hat jedoch ggü. der MIP-Map-Stufe 0 eine kleinere "Verschiebung", die oben mal gezeigt wurde.
Nun die Frage, ob man mit kluger Gewichtung nicht auch gleich TF machen kann. Dass "echtes" TF aus einer MIP-Map 16 Texel braucht und nicht 9, könnte man "philosophisch" damit erklären, dass eben der "Verschiebe-Fehler" weggelassen wird.
Aber ich habe das ungute Gefühl, dabei selbst einen Fehler zu machen.
zeckensack
2003-11-03, 20:10:02
Original geschrieben von aths
Zeckischnucki,
ich denke wir reden jetzt eine gemeinsame Sprache. Da ich leider gerne alles selbst herleite ist es wahrscheinlich, dass ich Begriffe auf ungebräuchliche Weise verwende.
Allerdings weiß ich noch nicht, wie du das mit der unendlich feinen Auflösung meinst - sprichst du den endlich aufgelösten Fraktionsteil an?Ich meine damit, daß die blauen Rechtecke aus deinen Skizzen halb (oder eben auch in beliebigen Stufen) in ein Texel hineinragen können. Es gibt aber nur für die kompletten Texel überhaupt Daten. Man kann nicht das 'untere linke Viertel' eines Texels (aus Mip-Level 0) benutzen, denn es existiert eben nicht in dieser Auflösung. Entweder man nimmt ein Roh-Texel ganz oder garnicht, die Mischung muß dann zwangsläufig über eine Gewichtung erfolgen.
Die Auflösung dieser Gewiche selbst stand eigentlich nicht zur Debatte (5 Bit oder wie war das noch?) ;)
Das mit dem 3x3-Körnel würde ich gerne erst mal noch zurück stellen.Oooch ;(
Immer unter der Annahme, daß die Miplevel mit einem 2x2 Box-Filter erzeugt werden, und nur linear gerechnet wird (!=Gammakorrigiert), ist das äquivalent.
Es ist trotzdem nicht schlecht, weil man (entgegen deiner Annahme) Texturcache effizienter nutzt. Von wegen Lokalität und so, das 'Umland' eines Texels ist sehr wahrscheinlich im Cache, denn die zugehörigen Pixel, die dieses Umland bereits brauchten, werden zeitnah gerendert.
Wenn man mit einem 2x2-Kernel filtert (und dazu 9 Texel braucht) kann man ja immer ein MIP-Level "weiter vorne" nehmen. Man generiert sich quasi die eigentlich gebrauchte MIP-Map selbst, hat jedoch ggü. der MIP-Map-Stufe 0 eine kleinere "Verschiebung", die oben mal gezeigt wurde.
Nun die Frage, ob man mit kluger Gewichtung nicht auch gleich TF machen kann. Dass "echtes" TF aus einer MIP-Map 16 Texel braucht und nicht 9, könnte man "philosophisch" damit erklären, dass eben der "Verschiebe-Fehler" weggelassen wird.
Aber ich habe das ungute Gefühl, dabei selbst einen Fehler zu machen. Da muß ich noch ein wenig grübeln :grübel:
Was genau erzeugst du aus 9 Samples? Kannst du mal ein entsprechendes Grid skizzieren?
Du brauchst doch schon vier Samples, um überhaupt Bilinear zu erzeugen :|
Demirug
2003-11-03, 20:46:08
aths, wenn du darauf bestehst das so Tri gefiltert wird wie es in der OpenGL Spec steht und nur eine Mipmap benutzten willst kommst du um das 4*4 Abtastraster nicht herum.
Mit einem 3*3 Abtastraster kann man natürlich auch was schönes machen aber eben kein TRI.
PS: Könneten wir uns darauf einigen das wenn wir von einem Filterkernel sprechen damit die benutzten Texel meinen?
Original geschrieben von zeckensack
Ich meine damit, daß die blauen Rechtecke aus deinen Skizzen halb (oder eben auch in beliebigen Stufen) in ein Texel hineinragen können. Es gibt aber nur für die kompletten Texel überhaupt Daten. Man kann nicht das 'untere linke Viertel' eines Texels (aus Mip-Level 0) benutzen, denn es existiert eben nicht in dieser Auflösung. Entweder man nimmt ein Roh-Texel ganz oder garnicht, die Mischung muß dann zwangsläufig über eine Gewichtung erfolgen.Das Gewicht entspricht der Fläche der Überdeckung des Kernels in das Texel. Ist 1/4 vom Texel mit dem Kernel überdeckt, fließt das Texel mit 0.25 ein. So ist gemeint, dass das "untere linke Viertel" genutzt wird.
Original geschrieben von zeckensack
Du brauchst doch schon vier Samples, um überhaupt Bilinear zu erzeugen :| Ok, lösen wir uns mal für den Moment von der Anzahl der Samples. Reden wir von der Kernel-Fläche. BF nutzt idealerweise ein 1:1 Texel-Pixel-Ratio. Der Kernel ist demnach auch von der Größe 1x1. Es fließt aus der Textur etwas ein, was 1 Texel "groß" ist, nur können eben "Zwischenfarben" interpoliert werden. Bei einem Ratio von > 1:1 kommt es zur Unterabtastung. Bei einem Ratio von < 1:1 kommt es zur Überfilterung. Ab 0,5:1 kann die nächsthöher aufgelöste MIP-Map genommen werden.
Bei einem Kernel mit der Fläche 2x2 kann sowieso immer die nächsthöher aufgelöste MIP-Map genommen werden. Das kleinere MIP-Level wird ja per 2x2-Blockfilter berechnet, durch den frei positionierbaren Kernel können wir sozusagen on the fly eine MIP-Farbe generieren. Oder anders gesagt, wir gleichen die Unterabtastung die beim 1x1-Kernel vorliegt durch eine größere Kernel-Fläche aus, was bis 2:1 funktioniert (wenn das Texel:Pixel-Ratio nicht von der Fläche, sondern von der Seitenkante betrachtet wird.)
Um einen 2x2-Kernel frei setzen zu können, braucht man 3x3 Samples, da es ja "Rand-Samples" geben kann.
http://www.aths.net/files/td22.gif http://www.aths.net/files/td22zs.gif
Die Texel ganz links bzw. ganz unten bleiben nun unberücksichtigt. Aber brauchen wir die überhaupt für ein vernünftiges Ergebnis?
Erst mal, um "besser als trilinear" zu samplen, muss man erst mal vermeiden dass beim Übergang von einem Mip-Level zum anderen ein Sprung, also Mip-Banding entsteht. Der Filterkernel muss also langsam wachsen. Bei Trilinear geschieht das dadurch dass die "äußeren" Texel mit steigendem Anteil berücksichtigt werden.
Die ängehängte Darstellung zeigt links LOD=0, mittig trilinear mit LOD=0,5 und rechts LOD=1. Das Blau zeigt, wie stark ein Texel der Basistextur auf die Pixelfarbe Einfluss nimmt (skaliert).
Original geschrieben von Xmas
Erst mal, um "besser als trilinear" zu samplen, muss man erst mal vermeiden dass beim Übergang von einem Mip-Level zum anderen ein Sprung, also Mip-Banding entsteht.Ach nee :)
Original geschrieben von Xmas
Der Filterkernel muss also langsam wachsen.Bzw. das höhere MIP-Level muss allmählich stärker berücksichtigt werden (läuft auf das gleiche hinaus.)
Der Kernel ist ja, wie man im 2. Bild des 1. Postings sieht, klein genug dass 3x3 ausreichen müssten. Hab ich da nun einen Denkfehler oder nicht?
Original geschrieben von aths
Ach nee :)
Bzw. das höhere MIP-Level muss allmählich stärker berücksichtigt werden (läuft auf das gleiche hinaus.)
Der Kernel ist ja, wie man im 2. Bild des 1. Postings sieht, klein genug dass 3x3 ausreichen müssten. Hab ich da nun einen Denkfehler oder nicht?
Ja. Denn wenn du 3x3 verwendest, bekommst du Banding wenn du von einem Mip-Level zum nächsten wechselst (was ja irgendwann unvermeidlich ist). Weil du im einen Moment, wenn die Kantenlänge des Kernels gerade 2 ist, 3x3 Texel aus der Basistextur beachtest, und wenn die Kantenlänge noch weiter wächst, du auf die nächste Mipmap springen musst. Dort nimmst du zwar nur 2x2 Texel, die aber 4x4 der Basistextur entsprechen. Es haben also plötzlich Texel Einfluss auf das Ergebnis, die vorher nicht beachtet wurden.
Demirug
2003-11-05, 17:05:40
aths, da du deine Filterfläche immer als Rechteck welches parrallel zum Textureraster liegt zeichnets bin ich mir jetzt nicht sicher ob du bei deinen Überlegeungen folgenden Tatsache berücksichtigst. Bei der Transformation eines Pixels von Screenspace in den Texturespace ist eine Rechteck desen Kanten in der von dir gezeichneten Art liegen ein absoluter Ausnahmefall.
Demirug, Bilinear und Trilinear arbeiten aber doch genau so, vom Samplepunkt ausgehend. Das Rechteck stellt dann nur die entsprechende Gewichtung dar.
Demirug
2003-11-05, 17:36:07
Original geschrieben von Xmas
Demirug, Bilinear und Trilinear arbeiten aber doch genau so, vom Samplepunkt ausgehend. Das Rechteck stellt dann nur die entsprechende Gewichtung dar.
Ja, natürlich aber aths möchte sich ja von dem default Verfahren entfernen und dafür sollte man IMHO diese Sache schon berücksichtigen. Und bei der LOD Berechung in Verbindung mit tri spielt es ja auch schon eine Rolle.
Original geschrieben von Demirug
aths, da du deine Filterfläche immer als Rechteck welches parrallel zum Textureraster liegt zeichnets bin ich mir jetzt nicht sicher ob du bei deinen Überlegeungen folgenden Tatsache berücksichtigst. Bei der Transformation eines Pixels von Screenspace in den Texturespace ist eine Rechteck desen Kanten in der von dir gezeichneten Art liegen ein absoluter Ausnahmefall. Ja, dafür gibt's dann ja AF, wenn man kein Quadrat im Texture Space hat.
Original geschrieben von Xmas
Es haben also plötzlich Texel Einfluss auf das Ergebnis, die vorher nicht beachtet wurden. Gnnnn. Stimmt. Leider. Dann brauchts wohl entweder 2x 3x3 oder 1x 5x5.
vBulletin®, Copyright ©2000-2024, Jelsoft Enterprises Ltd.