Ich mache einen Software-Rasterer, und ich habe in ein bisschen ein Haken geraten: Ich kann nicht scheinen, um Perspektive-korrekte Textur Mapping zu arbeiten.Perspektive korrekte Textur Mapping; Z-Abstand Berechnung könnte falsch sein
Mein Algorithmus ist zuerst die Koordinaten zu sortieren, um durch y
zu plotten. Dies gibt einen höchsten, niedrigsten und Mittelpunkt zurück. Ich gehe dann über die Abtastlinien des Deltas mit:
// ordering by y is put here
order[0] = &a_Triangle.p[v_order[0]];
order[1] = &a_Triangle.p[v_order[1]];
order[2] = &a_Triangle.p[v_order[2]];
float height1, height2, height3;
height1 = (float)((int)(order[2]->y + 1) - (int)(order[0]->y));
height2 = (float)((int)(order[1]->y + 1) - (int)(order[0]->y));
height3 = (float)((int)(order[2]->y + 1) - (int)(order[1]->y));
// x
float x_start, x_end;
float x[3];
float x_delta[3];
x_delta[0] = (order[2]->x - order[0]->x)/height1;
x_delta[1] = (order[1]->x - order[0]->x)/height2;
x_delta[2] = (order[2]->x - order[1]->x)/height3;
x[0] = order[0]->x;
x[1] = order[0]->x;
x[2] = order[1]->x;
Und dann machen wir order[0]->y
-order[2]->y
, die x_start
und x_end
durch eine Delta erhöht. Beim Rendern des oberen Teils sind die Delta-Werte x_delta[0]
und x_delta[1]
. Beim Rendern des unteren Teils sind die Delta-Werte x_delta[0]
und x_delta[2]
. Dann interpolieren wir linear zwischen x_start und x_end auf unserer Scanline. UV-Koordinaten werden auf die gleiche Weise interpoliert, geordnet nach y, beginnend am Anfang und Ende, auf die bei jedem Schritt Deltas angewendet werden.
Dies funktioniert gut, außer wenn ich versuche, Perspektive korrekte UV-Mapping zu tun. Der grundlegende Algorithmus besteht darin, für jeden Knoten UV/z
und 1/z
zu nehmen und zwischen ihnen zu interpolieren. Für jedes Pixel wird die UV-Koordinate UV_current * z_current
. Dies ist jedoch das Ergebnis:
Der inversed Teil der Ihnen sagt, wo das Delta des gespiegelt werden. Wie Sie sehen können, scheinen die beiden Dreiecke zu verschiedenen Punkten im Horizont zu gehen.
Hier ist, was ich verwenden, um die Z an einem Punkt im Raum zu berechnen:
float GetZToPoint(Vec3 a_Point)
{
Vec3 projected = m_Rotation * (a_Point - m_Position);
// #define FOV_ANGLE 60.f
// static const float FOCAL_LENGTH = 1/tanf(_RadToDeg(FOV_ANGLE)/2);
// static const float DEPTH = HALFHEIGHT * FOCAL_LENGTH;
float zcamera = DEPTH/projected.z;
return zcamera;
}
Bin ich richtig, ist es ein z-Puffer Problem?
andere Spitze für das Debugging, berechnet, jeden Punkt die Textur altmodischen, nicht-inkrementellen U und V unter Verwendung von für jeden Bildpunkt-Koordinaten und durch Ihren Algorithmus (unter Berücksichtigung einiger Slop wegen Rundungsfehlern), berechnet auf die inkrementellen Werte vergleichen. –
Wow ... das ist eine Antwort und eine Hälfte! : D – Goz
goz: hoffen jetzt nur nützlich es ist, da er wahrscheinlich durch das Bild zu urteilen die meisten dieser Code bereits vorhanden ist. Ich denke, dass er wahrscheinlich einen der Interpolationswerte falsch berechnet hat. Aber hoffentlich, wenn er neben mir seinen Algorithmus legt kann er herausfinden, welches es ist; ^) – Toad