Ich habe einige Probleme beim Rendern einer Reihe von Werten für ein Rendertarget. Die Werte landen nie genau in dem Bereich, den ich möchte. Grundsätzlich verwende ich ein Vollbild-Quad und einen Pixel-Shader, um meine Rendertarget-Textur zu rendern, und beabsichtige dann, die Texturkoordinaten als Grundlage für einige Berechnungen im Shader zu verwenden. Die Texturkoordinaten des Quad reichen von (0,0) oben links bis (1,1) unten rechts. Das Problem ist, dass diese Werte nach der Interpolation nicht als solche zum Pixel-Shader gelangen .
Ein Beispiel: Ich rendere in eine 4x4-Textur und der Shader gibt in diesem Fall einfach die Texturkoordinaten (u, v) in den roten und grünen Kanälen aus:
return float4(texCoord.rg, 0, 1);
Was ich daraus machen möchte, ist eine Textur, bei der das Pixel oben links RGB (0,0,0) und damit schwarz ist, das Pixel oben rechts RGB (255,0,0) und somit hell ist rot und das Pixel unten links ist RGB (0,255,0) - ein helles Grün.
Stattdessen bekomme ich das hier rechts:
(Straight Quad Rendering, keine Korrektur)
Das Pixel oben links ist schwarz, aber ich bekomme nur in den anderen Ecken ein relativ dunkles Rot und Dunkelgrün. Ihre RGB-Werte sind (191,0,0) und (0,191,0). Ich vermute sehr, dass dies mit den Abtastorten des Quad zu tun hat: Das obere linke Pixel tastet die obere linke Ecke des Quad korrekt ab und erhält (0,0) als UV-Koordinaten, aber die anderen Eckpixel werden nicht abgetastet die anderen Ecken des Quad. Ich habe dies im linken Bild mit dem blauen Kästchen dargestellt, das das Quad darstellt, und den weißen Punkten, die die oberen Abtastkoordinaten darstellen.
Jetzt weiß ich um den halben Pixelversatz, den Sie beim Rendern von Quads mit Bildschirmausrichtung in Direct3D9 auf Ihre Koordinaten anwenden sollten. Mal sehen, was für ein Ergebnis ich daraus bekomme:
(Quad mit DX9s halbem Pixelversatz gerendert)
Rot und Grün sind heller geworden, aber immer noch nicht korrekt: 223 ist das Maximum, das ich auf dem roten oder grünen Farbkanal bekomme. Aber jetzt habe ich nicht einmal mehr reines Schwarz, sondern ein dunkles, gelbliches Grau mit RGB (32,32,0)!
Was ich eigentlich brauche, wäre diese Art von Rendering:
(Zielrender, reduzierte Quad-Größe)
Es sieht so aus, als müsste ich den rechten und den unteren Rand meines Quad im Vergleich zur ersten Figur genau um ein Pixel nach oben und links verschieben. Dann sollten die rechte Spalte und die untere Pixelreihe die UV-Koordinaten direkt vom Rand des Quadrats korrekt erhalten:
VertexPositionTexture[] quad = new VertexPositionTexture[]
{
new VertexPositionTexture(new Vector3(-1.0f, 1.0f, 1f), new Vector2(0,0)),
new VertexPositionTexture(new Vector3(1.0f - pixelSize.X, 1.0f, 1f), new Vector2(1,0)),
new VertexPositionTexture(new Vector3(-1.0f, -1.0f + pixelSize.Y, 1f), new Vector2(0,1)),
new VertexPositionTexture(new Vector3(1.0f - pixelSize.X, -1.0f + pixelSize.Y, 1f), new Vector2(1,1)),
};
Dies hat jedoch nicht ganz geklappt und dazu geführt, dass die unteren und rechten Pixel überhaupt nicht gerendert wurden. Ich nehme an, dass die Zentren dieser Pixel nicht mehr vom Quad abgedeckt werden und daher nicht vom Shader verarbeitet werden. Wenn ich die pixelSize-Berechnung um einen winzigen Betrag ändere, um das Quad um einen winzigen Betrag zu vergrößern, funktioniert es irgendwie ... zumindest bei einer 4x4-Textur. Es funktioniert nicht bei kleineren Texturen und ich befürchte, dass es die gleichmäßige Verteilung der UV-Werte auch bei größeren Texturen auf subtile Weise verzerrt:
Vector2 pixelSize = new Vector2((2f / textureWidth) - 0.001f, (2f / textureHeight) - 0.001f);
(Ich habe die pixelSize-Berechnung um 0,001 f geändert. Bei kleineren Texturen, z. B. 1D-Nachschlagetabellen, funktioniert dies nicht und ich muss sie auf 0,01 f oder etwas Größeres erhöhen.)
Natürlich ist dies ein triviales Beispiel, und ich könnte diese Berechnung auf der CPU viel einfacher durchführen, ohne mir Gedanken über die Zuordnung von UV-Strahlen zu Pixelzentren machen zu müssen. Dennoch muss es eine Möglichkeit geben, tatsächlich eine vollständige [0] zu rendern. 1] Bereich bis Pixel auf einem Rendertarget!?