[D3D] Textur NUR bei Vergrößerung pixelig samplen

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

[D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Krishty »

Hi,

Ich möchte einen Bildschirm stark vergrößert Rendern, so dass man die einzelnen Subpixel erkennen kann. Der Bildschirminhalt liegt dabei als Textur vor. Der Plan war also:
  • Textur mit Punktfilterung samplen
  • Eine Detailtextur, wo die rot-grün-blauen Subpixel drauf sind, in einer Kachelung drüberzeichnen, so dass jede Kachel exakt einen Pixel der Bildschirmtextur abdeckt (die Details lasse ich hier mal außen vor)
So weit, so gut. Problematisch wird nun aber, wenn der Bildschirm nicht nur stark vergrößert dargestellt werden soll, sondern normal weit weg: Dann beginnt die Textur wie blöd zu flimmern weil … weil ich ja eben Punktfilterung benutze.

Also muss der Filter für Verkleinerung und Mip-Levels angepasst werden. So weit ich das sehe, bietet Direct3D 10 z.B. den Filtertyp D3D10_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR, wo die Textur nur in der Vergrößerung Punktfilterung nutzt und sonst lineare Filterung.

Deutlich besser, aber noch nicht optimal: Trilineare Filterung sieht immernoch, gelinde gesagt, bescheiden aus im Vergleich zu anisotroper Filterung.

Ist es möglich, für Minification und Mip einen anisotropen Filter zu setzen, aber für Magnification Punktfilterung?

Da Direct3D 11 keinen entsprechenden Filter-Typ anbietet wäre die Antwort intuitiv Nein, aber vielleicht fällt jemandem ein, ob man an der Textur selber oder in den Shadern was drehen könnte?

Wie sieht das in Direct3D 9 aus, wo man die drei Filter noch beliebig seperat einstellen kann: Wird das von irgendeiner aktuellen Hardware unterstützt?
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Krishty »

Okay – ich kann im Shader via ddx und ddy die Ableitung der Texturkoordinaten bestimmen. Ist sie so groß, dass die Textur im Bereich der Vergrößerung liegt, korrigiere ich die Texturkoordinaten so, dass sie allesamt auf der Pixel-Mitte liegen (manuelles Point Filtering quasi). Der Nachkommateil, der dabei übrig bleibt, wird für die Textur mit den RGB-Subpixel benutzt (oder man baut direkt ein if in den Shader ein: erstes Drittel rot, zweites Drittel grün, Rest blau; aber dann wird nicht schön gefiltert).

Ziemlich eklig; und ich glaube nicht, dass es auf Shader Model 2.0 gehen wird …
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Artificial Mind »

Interessanterweise muss man in OpenGL Min- und Mag-Filter getrennt setzen. Und dort funktioniert es auch prima wenn man Mag-Filter auf GL_NEAREST und Min-Filter auf GL_LINEAR_MIPMAP_LINEAR setzt...

EDIT: Das müsste deine Frage nach Hardwaresupport klären, oder?
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Niki »

Krishty hat geschrieben:Ziemlich eklig; und ich glaube nicht, dass es auf Shader Model 2.0 gehen wird …
Ja, ddx und ddy gibt's in ps_2_0 noch nicht. Erst ab ps_2_x. Bist du denn in der Situation wo du 2.0 nicht ignorieren kannst? Das ist ja nun schon sehr alt.

Aber eins verstehe ich nicht ganz... wieso flimmert dein Bild wenn du es 1:1 darstellst? Oder wird das Bild etwas verschoben, wie bei einem scrollenden Hintergrund? Oder wird es vielleicht sogar rotiert? Irgendwo muss der Grund für das Flimmern ja herkommen.
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Krishty »

Artificial Mind hat geschrieben:Interessanterweise muss man in OpenGL Min- und Mag-Filter getrennt setzen. Und dort funktioniert es auch prima wenn man Mag-Filter auf GL_NEAREST und Min-Filter auf GL_LINEAR_MIPMAP_LINEAR setzt...

EDIT: Das müsste deine Frage nach Hardwaresupport klären, oder?
Nein:
Krishty hat geschrieben:So weit ich das sehe, bietet Direct3D 10 z.B. den Filtertyp D3D10_FILTER_MIN_LINEAR_MAG_POINT_MIP_LINEAR, wo die Textur nur in der Vergrößerung Punktfilterung nutzt und sonst lineare Filterung.

Deutlich besser, aber noch nicht optimal: Trilineare Filterung sieht immernoch, gelinde gesagt, bescheiden aus im Vergleich zu anisotroper Filterung.
Dass es trilineare Filterung nur für Min / Mip gibt weiß ich, aber gibt es auch anisotrope nur dafür?
Niki hat geschrieben:Ja, ddx und ddy gibt's in ps_2_0 noch nicht. Erst ab ps_2_x. Bist du denn in der Situation wo du 2.0 nicht ignorieren kannst? Das ist ja nun schon sehr alt.
Nein; ich bin leider XP-gebunden :(
Niki hat geschrieben:Aber eins verstehe ich nicht ganz... wieso flimmert dein Bild wenn du es 1:1 darstellst?
Achso – ich vergaß zu erwähnen, der Bildschirm steht in einer 3d-Szene. Man kann sich also frei drumherum bewegen, und auch recht weit davon weg sein. Da ist nicht viel mit 1:1-Darstellung.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
dot
Establishment
Beiträge: 1734
Registriert: 06.03.2004, 18:10
Echter Name: Michael Kenzel
Kontaktdaten:

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von dot »

Krishty hat geschrieben:Dass es trilineare Filterung nur für Min / Mip gibt weiß ich, aber gibt es auch anisotrope nur dafür?
Was würde AF beim Mag Filter denn bringen, afaik ist der ganze Sinn von AF doch auch nur, bestimmte Aliasingeffekte zu minimieren? Ich kann mir ehrlich gesagt nichtmal vorstellen, was ein anisotropischer Mip Filter eigentlich genau tun sollte (der Begriff allein macht in dem Kontext imo schon keinen Sinn). Zumindest nach meinem Verständnis tut AF jedenfalls nix andres, als die Textur adaptiv in die für Aliasing lokal schlimmste Richtung stärker zu samplen!? Die Art von Aliasing, die man mit AF dämpfen will, tritt bei Vergrößerung doch rein prinzipiell schon gar nicht auf!?
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Niki »

Krishty hat geschrieben:Dass es trilineare Filterung nur für Min / Mip gibt weiß ich, aber gibt es auch anisotrope nur dafür?
In D3D10/11 bezieht sich, lt. Dokumentation, der anisotropische Filter auf Min/Max/Mip gleichzeitig und kann nicht separat angegeben werden. In D3D9 könnte es vielleicht gehen wenn die Grafikkarte die entsprechenden Caps hat (siehe D3DPTFILTERCAPS).

Eine Pixel-Shader-Lösung mit PS <= 2.0 kann ich mir grad nicht vorstellen. Irgendwie scheint mir das man ddx/ddy schon braucht wenn man quasi einen eigenen Filter schreibt. In begrenztem Sinne tust du das ja mit deinem ddx/ddy-Ansatz.

Auch einen geometrischen Ansatz zur Auswahl eines bestimmten Filters sehe ich jetzt nicht, denn wenn der Bildschirm im 3D Raum steht, dann kann es ja sein das sich der Filter irgendwo in der Mitte des Bildschirms ändern müsste.

Ich habe da eine Art Hack-Idee, aber ob (und auch wie) man damit wirklich ans Ziel kommt kann ich nicht mal eben so abschätzen. Damit muss man schon rumspielen:

Du hast 2 Texturen, A und B. Beide haben die komplette Mipmap-Chain, sagen wir mal 8 Miplevels pro Textur. In Textur A ist Mip-Level 0 volltransparent und Mip-Levels 1-7 sind normal. In Texture B ist Mip-Level 0 normal, und Mip-Level 1-7 sind volltransparent. Jetzt zeichnest du den Bildschirm zweimal. Einmal mit Texture A und anisotropischem Filter, und einmal mit Textur B mit Punktfilter.

Kranker Ansatz, aber in der Not kommt man halt auch auf kranke Ideen :)
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Krishty »

dot hat geschrieben:
Krishty hat geschrieben:Dass es trilineare Filterung nur für Min / Mip gibt weiß ich, aber gibt es auch anisotrope nur dafür?
Was würde AF beim Mag Filter denn bringen,[…] Die Art von Aliasing, die man mit AF dämpfen will, tritt bei Vergrößerung doch rein prinzipiell schon gar nicht auf!?
Gerade bei Mag will ich den anisotropen Filter ja NICHT, sondern überall sonst, und bei Mag nur Punktfilterung!
Niki hat geschrieben:Ich habe da eine Art Hack-Idee, aber ob (und auch wie) man damit wirklich ans Ziel kommt kann ich nicht mal eben so abschätzen. Damit muss man schon rumspielen:

Du hast 2 Texturen, A und B. Beide haben die komplette Mipmap-Chain, sagen wir mal 8 Miplevels pro Textur. In Textur A ist Mip-Level 0 volltransparent und Mip-Levels 1-7 sind normal. In Texture B ist Mip-Level 0 normal, und Mip-Level 1-7 sind volltransparent. Jetzt zeichnest du den Bildschirm zweimal. Einmal mit Texture A und anisotropischem Filter, und einmal mit Textur B mit Punktfilter.

Kranker Ansatz, aber in der Not kommt man halt auch auf kranke Ideen :)
So krank ist der Ansatz garnicht; mir schwebte eben dasselbe vor. Man kann es sogar in einem einzigen Zeichendurchlauf erledigen, indem man einfach beide Texturen samplet und gemäß des Alphakanals im Shader interpoliert. Man braucht auch nur in einer der beiden Texturen ein Mip-Level zu löschen.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Niki »

Falls du's ausprobieren solltest... Lass uns Wissen ob die Rechnung aufgeht :D
Benutzeravatar
Artificial Mind
Establishment
Beiträge: 802
Registriert: 17.12.2007, 17:51
Wohnort: Aachen

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Artificial Mind »

Jetzt verstehe ich auch was das Problem mit dem AF ist: das greift eben auch bei Magnification, da es das Sample-Integral approximieren will und somit auch nah dran über Texelgrenzen hinweg "verwischt".
Bei OpenGL ist gar nicht spezifiziert was AF macht, da es komplett herstellerabhängig ist. Da gibt man nur einen float an, wie viele Samples er maximal machen soll.

Gibt es in DirectX soetwas wie Sampler-Objekte? also kann man eine Textur zweimal mit unterschiedlichem Sampling aber gleichen ("shared") Texturdaten binden? Wenn ja, dann kannst du die "kranke Idee" damit auch resourcensparend umsetzen.

Trotzdem löst es das Problem nicht ganz, oder? der Übergang zwischen Mip 0 und Mip 1 könnte zwischendurch relativ hart sein. Aber vielleicht ist das Ergebnis gut genug (oder "künstlerisch rechtfertigbar" ;) ).
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Krishty »

Artificial Mind hat geschrieben:Gibt es in DirectX soetwas wie Sampler-Objekte? also kann man eine Textur zweimal mit unterschiedlichem Sampling aber gleichen ("shared") Texturdaten binden? Wenn ja, dann kannst du die "kranke Idee" damit auch resourcensparend umsetzen.
Japp.
Trotzdem löst es das Problem nicht ganz, oder? der Übergang zwischen Mip 0 und Mip 1 könnte zwischendurch relativ hart sein. Aber vielleicht ist das Ergebnis gut genug (oder "künstlerisch rechtfertigbar" ;) ).
Die Mip-Übergänge sind bei anisotroper Filterung ja durchaus weich. Auf dem Übergang wird die anisotrop gefilterte Textur also langsam (und schön regelmäßig) an Alpha-Deckkraft verlieren. Noch dazu wird dieser Übergang wohl genau zwischen 1 und 2 Texeln pro Pixel liegen, wo sich der anisotrope und der Punktfilter halbwegs überlappen. Ich hoffe also, dass es hübsch aussieht.

Jetzt muss ich aber erstmal die Bildschirmtexturen gerendert kriegen bevor ich das alles ausprobieren kann :)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Krishty »

Nochmal genauer: Ich habe die Textur mit dem Bildschirminhalt. Wenn die auf dem Bildschirm kleiner dargestellt wird als mit einem Texel pro Pixel, soll sie anisotrop gefiltert werden. Sonst soll sie Punktfilterung benutzen, damit der virtuelle Bildschirm beim nahe-rangehen verpixelt aussieht.

Nun erzeuge ich also zu allererst Mip-Levels für diese Textur, damit der anisotrope Filter schön filtern kann.

Außerdem fülle ich danach den Alphakanal des am höchsten aufgelösten Mip-Levels mit 0, während er bei den anderen Mip-Levels 1 bleibt. Denn ich weiß: Wird das am höchsten aufgelöste Mip-Level verwendet, muss die Textur auf dem Bildschirm mit weniger als einem Texel pro Pixel, also originalgroß oder vergrößert, angezeigt werden.

Nun sample ich die Textur im Shader zwei Mal: Einmal mit Punktfilterung und einmal anisotropisch.

Dann benutze ich den Alphakanal des anisotropen Samplings: Dort, wo die Textur vergrößert wird, ist er 0. Dort, wo die Textur stark verkleinert wird, ist er 1. Dazwischen geht er weich über.

Ich benutze diesen Wert, um zwischen den beiden Samples, die ich eben gesammelt habe, zu interpolieren: 0 für das Punkt-Sample, und 1 für das anisotrope Sample. Das Ergebnis flitzt, ohne Alpha-Blending, in den Back Buffer (oder wird beleuchtet oder sonstwas).
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Niki
Establishment
Beiträge: 309
Registriert: 01.01.2013, 21:52

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Niki »

Heißt das es funzt wie erhofft? Wenn ja, dann Gratulation! :)
Benutzeravatar
Krishty
Establishment
Beiträge: 8268
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: [D3D] Textur NUR bei Vergrößerung pixelig samplen

Beitrag von Krishty »

Nein; alles Theorie ;) Wird noch dauern bis ich es probieren kann.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Antworten