Direktes Zuordnen von Texels zu Pixeln (Direct3D 9)
Bei der Render von 2D-Ausgängen unter Verwendung von vorverwandelten spitzen (vertices) muss darauf geachtet werden, dass jeder Texelbereich korrekt einem einzelnen Pixelbereich entspricht, da sonst eine Texturverzerrung auftreten kann. Durch das Verständnis der Grundlagen des Prozesses, den Direct3D beim Rasterisieren und Texturieren von Dreiecken verfolgt, können Sie sicherstellen, dass Ihre Direct3D-Anwendung korrekt die 2D-Ausgabe macht.
(bild 1)
Das vorstehende Diagramm zeigt Pixel, die als Quadrate modelliert sind. In Wirklichkeit sind jedoch Pixel Punkte, keine Quadrate. Jedes Quadrat im vorigen Diagramm zeigt den Bereich an, der durch das Pixel beleuchtet wird, aber ein Pixel ist immer nur ein Punkt in der Mitte eines Quadrats. Diese Unterscheidung, wenn auch scheinbar klein, ist wichtig. Eine bessere Darstellung der gleichen Anzeige ist im folgenden Diagramm dargestellt.
(Bild 2)
Das vorstehende Diagramm zeigt korrekt jeden physikalischen Pixel als Punkt in der Mitte jeder Zelle an. Die Bildschirmraumkoordinate (0, 0) befindet sich direkt am oberen linken Pixel und damit in der Mitte der oberen linken Zelle. Die obere linke Ecke des Displays liegt also bei (-0,5, -0,5), da es 0,5 Zellen nach links und 0,5 Zellen aus dem oberen linken Pixel gibt. Direct3D wird ein Quad mit Ecken an (0, 0) und (4, 4), wie in der folgenden Abbildung gezeigt.
(Bild 3)
Die vorstehende Abbildung zeigt, wo das mathematische Quad in Bezug auf dem Schaufenster steht, aber es zeigt nicht, wie das Quad aussehen wird, sobald Direct3D es rastert und es ans Display sendet. Tatsächlich ist es für eine Rasterdarstellung unmöglich, das Quad genau so zu füllen, wie es angezeigt wird, da die Kanten des Quads nicht mit den Grenzen zwischen Pixelzellen übereinstimmen. Mit anderen Worten, weil jedes Pixel nur eine einzelne Farbe anzeigen kann, wird jede Pixelzelle nur mit einer einzigen Farbe gefüllt; Wenn die Anzeige das Quad genau wie gezeigt darstellen würde, müssten die Pixelzellen entlang der Quad-Kante zwei verschiedene Farben zeigen: blau, wo das Quad und Weiß abgedeckt sind, wo nur der Hintergrund sichtbar ist.
Stattdessen wird die Grafikhardware beauftragt, festzustellen, welche Pixel gefüllt werden sollen, um das Quad zu approximieren. Dieser Vorgang wird als Rasterung bezeichnet und ist in Rasterisierungsregeln (Direct3D 9) beschrieben. Für diesen Fall ist das rasterisierte Quad in der folgenden Abbildung dargestellt.
(Bild 4)
Beachten Sie, dass das an Direct3D übergebene Quad an Ecken an (0, 0) und (4, 4) übergeben hat, aber die rasterisierte Ausgabe (die vorhergehende Abbildung) hat Ecken bei (-0,5, -0,5) und (3,5,3,5). Vergleichen Sie die beiden vorstehenden Abbildungen, um Unterschiede zu machen. Sie können sehen, dass das, was die Anzeige tatsächlich macht, die richtige Größe ist, aber um -0,5 Zellen in der x- und y-Richtung verschoben wurde. Allerdings, mit Ausnahme von Multi-Sampling-Techniken, ist dies die bestmögliche Annäherung an das Quad. (Siehe die Antialias-Probe für eine gründliche Abdeckung von Multi-Sampling.) Seien Sie sich bewusst, dass, wenn die Rasterer gefüllt jede Zelle das Quad gekreuzt, wäre die resultierende Fläche von Dimension 5 x 5 statt der gewünschten 4 x 4.
Wenn Sie davon ausgehen, dass die Bildschirmkoordinaten an der oberen linken Ecke des Anzeigegitters anstelle des oberen linken Pixels entstehen, erscheint das Quad genau wie erwartet. Der Unterschied wird jedoch deutlich, wenn dem Quad eine Textur gegeben wird. Die folgende Abbildung zeigt die 4 x 4 Textur, die du direkt auf das Quad karte.
(Bild 5)
Weil die Textur 4 x 4 texels gros ist und das Quad 4 x 4 Pixel ist, könnte man erwarten, dass das strukturierte Quad genau wie die Textur erscheint, unabhängig von der Position auf dem Bildschirm, wo das Quad gezeichnet wird. Dies ist jedoch nicht der Fall; Auch leichte Änderungen in der Position beeinflussen, wie die Textur angezeigt wird. Die folgende Abbildung zeigt, wie ein Quad zwischen (0, 0) und (4, 4) nach Rasterung und Textur angezeigt wird.
[Blockierte Grafik: http://img5.fotos-hochladen.net/thumbnail/ic412598h9fyqd7v3z_thumb.jpg]
Das in der vorstehenden Abbildung gezeichnete Quad weist den strukturierten Ausgang (mit einem linearen Filtermodus und einem Klemmenadressierungsmodus) mit dem überlagerten gerasterten Umriss auf. Der Rest dieses Artikels erklärt genau, warum die Ausgabe so aussieht, wie es anstatt wie die Textur aussieht, aber für diejenigen, die die Lösung wollen, hier ist es: Die Kanten des Eingabeviertels müssen auf den Grenzlinien zwischen Pixelzellen liegen . Durch einfaches Verschieben der x- und y-Quad-Koordinaten um -0,5 Einheiten werden Texelzellen perfekt Pixelzellen abdecken und das Quad kann auf dem Bildschirm perfekt neu erstellt werden. (Die letzte Abbildung in diesem Thema zeigt das Quad an den korrigierten Koordinaten.)
Die Details, warum die gerasterte Ausgabe nur eine geringe Ähnlichkeit mit der Eingabetextur hat, stehen in direktem Zusammenhang mit der Art und Weise, wie Direct3D-Adressen und Mustertexturen sind. Was folgt, Sie haben ein gutes Verständnis der Textur Koordinaten Raum und bilineare Textur Filterung.
Wenn wir zu unserer Untersuchung des seltsamen Pixelausgangs zurückkehren, ist es sinnvoll, die Ausgabefarbe wieder auf den Pixel-Shader zu verfolgen: Der Pixel-Shader wird für jedes ausgewählte Pixel aufgerufen, um Teil der gerasterten Form zu sein. Das feste blaue Quad, das in einer früheren Darstellung dargestellt wurde, könnte einen besonders einfachen Shader haben:
(Float 4 = Gleitkommazahl, eine Länge von 4 Bytes = 4 Hexa zahlen)
- float4 SolidBluePS() : COLOR
- {
- return float4( 0, 0, 1, 1 );
- }
Für den texturierten Quad muss der Pixel-Shader leicht geändert werden:
- texture MyTexture;
- sampler MySampler =
- sampler_state
- {
- Texture = <MyTexture>;
- MinFilter = Linear;
- MagFilter = Linear;
- AddressU = Clamp;
- AddressV = Clamp;
- };
- float4 TextureLookupPS( float2 vTexCoord : TEXCOORD0 ) : COLOR
- {
- return tex2D( MySampler, vTexCoord );
- }
Alles anzeigen
Dieser Code setzt voraus, dass die 4 x 4 Textur in MyTexture gespeichert ist. Wie gezeigt, wird bei der MySampler Textur Sampler gesetzt, um bilineare Filterung auf MyTexture durchzuführen. Der Pixel-Shader wird einmal für jedes gerasterte Pixel aufgerufen, und jedes Mal, wenn die zurückgegebene Farbe die abgetastete Texturfarbe bei vTexCoord ist. Jedes Mal, wenn der Pixel-Shader aufgerufen wird, wird das vTexCoord-Argument auf die Texturkoordinaten an diesem Pixel gesetzt. Das heißt, der Shader fragt den Textur-Sampler für die gefilterte Texturfarbe an der genauen Position des Pixels, wie in der folgenden Abbildung dargestellt.
[Blockierte Grafik: http://www.fotos-hochladen.net/thumbnail/ic412599h9nulf8zm7_thumb.jpg]
Die Textur (dargestellt überlagert) wird direkt an Pixelpositionen abgetastet (als schwarze Punkte dargestellt). Texturkoordinaten sind von der Rasterung nicht betroffen (sie bleiben im projizierten Bildschirmraum des ursprünglichen Quads). Die schwarzen Punkte zeigen, wo die Rasterung Pixel sind. Die Texturkoordinaten an jedem Pixel werden leicht durch Interpolation der an jedem Scheitelpunkt gespeicherten Koordinaten bestimmt: Das Pixel bei (0,0) fällt mit dem Scheitelpunkt bei (0, 0) zusammen; Daher sind die Texturkoordinaten an diesem Pixel einfach die Texturkoordinaten, die an diesem Scheitelpunkt gespeichert sind, UV (0,0, 0,0). Für das Pixel bei (3, 1) sind die interpolierten Koordinaten UV (0,75, 0,25), weil dieses Pixel bei drei Vierteln der Texturbreite und einem Viertel seiner Höhe liegt. Diese interpolierten Koordinaten sind an den Pixel-Shader übergeben.
Die Texel richten sich in diesem Beispiel nicht mit den Pixeln aus. Jedes Pixel (und damit jeder Abtastpunkt) ist an der Ecke von vier Texeln positioniert. Da der Filtermodus auf Linear eingestellt ist, wird der Sampler die Farben der vier Texte, die diese Ecke teilen, durchschnittlich Dies erklärt, warum das Pixel, das erwartet wird, dass es rot ist, tatsächlich drei Viertel Grau plus ein Viertel rot ist, das Pixel, das erwartet wird, grün zu sein, ist ein halbes Grau plus ein Viertel rot plus ein Viertel grün und so weiter.
Um dieses Problem zu beheben, alles, was Sie tun müssen, ist korrekt Karte der Quad auf die Pixel, auf die es gerastert werden, und damit korrekt Karte die Texel auf Pixel. Die folgende Abbildung zeigt die Ergebnisse der Zeichnung der gleichen Quad zwischen (-0,5, -0,5) und (3,5, 3,5), die das Quad von Anfang an beabsichtigt ist.
[Blockierte Grafik: http://img5.fotos-hochladen.net/thumbnail/ic4126000dtgnpq9ml_thumb.jpg]
Die vorstehende Abbildung zeigt, dass das Quad (dargestellt von (-0,5, -0,5) bis (3,5, 3,5)) genau dem gerasterten Bereich entspricht.
Zusammenfassung
Zusammenfassend sind Pixel und Texel eigentlich Punkte, keine festen Blöcke. Der Bildschirmbereich entsteht am oberen linken Pixel, aber Texturkoordinaten entspringen an der oberen linken Ecke des Texturraster. Am wichtigsten ist, denken Sie daran, 0,5 Einheiten von den x- und y-Komponenten Ihrer Scheitelpositionen zu subtrahieren, wenn Sie im transformierten Bildschirmbereich arbeiten, um Texel mit Pixeln korrekt auszurichten.