Ich versuche also, meine Texturen in meinem Software-Renderer mithilfe der u, v-Koordinaten korrekt zuzuordnen, aber ich kann es scheinbar nicht zum Laufen bringen. Ich habe affine Textur-Mapping funktioniert. Das kann ich damit produzieren:
Sie können an der "Neigung" in der Textur erkennen, dass es nicht ganz richtig ist. Wenn ich dem Netz mehr Dreiecke hinzufüge, wird es korrekter. Nach meinem Verständnis sind dies keine perspektivisch korrekten Texturen. Aber diese Perspektiventeilung verwirrt mich. Ich habe gelesen, dass ich die u, v-Koordinaten durch die w-Komponente teilen muss (perspektivische Teilung). Ich vermute, dass dies die w-Komponente vom Scheitelpunkt ist, nachdem sie mit der Projektionsmatrix multipliziert wurde. Aber ich konnte das auch nicht zum Laufen bringen. Also habe ich mich ein bisschen mehr mit dem Problem befasst. Zuerst passiert Folgendes mit einem Scheitelpunkt meiner Dreiecke.
float4 pt1 = worldViewProj * mesh->vertices[mesh->indices[i]];
float2 uv1 = mesh->texCoords[mesh->indices[i]];
triangle.p1 = float3((pt1.x / pt1.w + 0.5f) * screen->GetScreenWidth(), (pt1.y / pt1.w + 0.5f) * screen->GetScreenHeight(), pt1.w);
Ich multipliziere es mit dem wVP und teile dann meine Perspektive mit x und y. Das + 0.5f dient dazu, es im homogenen Raum zu zentrieren und dann mit den Bildschirmabmessungen zu multiplizieren, um es im Bildschirmraum zu erhalten. Ich fülle dann die w-Komponente des Scheitelpunkts als z-Wert ein, damit sie an die Dreieckszeichnungsfunktion gesendet wird und für Dinge wie den Tiefenpuffer verwendet werden kann.
Nach meinem Verständnis wird der z-Wert vom Scheitelpunkt nach Multiplikation mit der Projektionsmatrix in w gesetzt. Dies ist sinnvoll, da in meiner Projektionsmatrix m32 = 1 ist. Also nach Multiplikation mit der Projektionsmatrix w = z. Ich habe zuerst versucht, die Texturkoordinaten pro Scheitelpunkt durch w zu teilen. Wie so:
float2 uv1 = mesh->texCoords[mesh->indices[i]] / w;
Dann habe ich in der Dreieckszeichnungsfunktion die zentrischen Koordinaten verwendet, um über diese die UV-Koordinaten zu interpolieren. Das hat nicht funktioniert. Da w = z. Wenn die Textur weit von der Kamera entfernt ist (dh z ist ein großer Wert. Wenn meine Weltübersetzungen auf z = ~ 700 angewendet werden), schrumpfen die Texturkoordinaten stark und bei jedem Rendern erhalte ich nur den (0, 0) -Wert meiner Textur .
Aber ich habe dies stattdessen auch in meiner Dreieckszeichnungsfunktion versucht:
float2 texCoord = (texCoord1 * u + texCoord2 * v + texCoord3 * w) / z;
(Hier sind u, v und w die zentrischen Koordinaten. Jeder texCoord ist die Texturkoordinate an diesem Scheitelpunkt.) Der Unterschied besteht darin, dass der interpolierte z-Wert an jedem Pixel geteilt wird, anstatt an den Scheitelpunkten. So oder so kann ich es nicht zu gut zum Laufen bringen. Wieder ist der z-Wert zu groß und ich bekomme am Ende (0, 0).
Also untersuche ich, was ich brauche, um u und v durch zu teilen. Offensichtlich mache ich etwas falsch. Ist es wirklich die w-Komponente des Scheitelpunkts nach Multiplikation mit der Projektionsmatrix? Ist mein w-Wert falsch? Könnte die Projektionsmatrix dies verursachen? Ich habe jetzt eine Weile gegoogelt ... x / w und y / w sind [-1, 1] (homogen), aber z ist nicht [-1, 1]. Soll es sein Meine Perspektiventeilung für x und y funktioniert offensichtlich.
So habe ich meine Projektionsmatrix für den Fall erstellt, dass sie falsch ist?:
float tanHalfFov = tanf(fov * 0.5f * 3.14f / 180.0f);
float s = 1.0f / (tanHalfFov * aspectRatio);
float zRange = farZ - nearZ;
// Set the projection matrix
proj.m00 = s; proj.m01 = 0.0f; proj.m02 = 0.0f; proj.m03 = 0.0f;
proj.m10 = 0.0f; proj.m11 = aspectRatio * s; proj.m12 = 0.0f; proj.m13 = 0.0f;
proj.m20 = 0.0f; proj.m21 = 0.0f; proj.m22 = farZ / zRange; proj.m23 = farZ * nearZ / zRange;
proj.m30 = 0.0f; proj.m31 = 0.0f; proj.m32 = 1.0f; proj.m33 = 0.0f;
w
zusätzlich zu Ihren Raumkoordinaten (x, y und möglicherweise z) ein haben. Es hat nichts mit Normalisierung zu tun. Sie dividieren nie durch Z - immer W. Der Punkt von W ist, dass Sie die Perspektive perspektivisch teilen und die Tiefe beibehalten können (wieder im Clip-Bereich) und die Übersetzung in Ihre Matrix einfügen können, anstatt einen separaten Schritt zu haben. Sie vermischen viele verschiedene Konzepte.