Ich versuche, Texturen für Kugeln in meinem Raytracer zu implementieren. Es ist mir gelungen, etwas zum Laufen zu bringen, aber ich bin mir nicht sicher, ob es korrekt ist. Unten ist der Code zum Abrufen der Texturkoordinaten. Momentan ist die Textur zufällig und wird zur Laufzeit generiert.
%Vor%So sehen jetzt die Kugeln aus:
Ich musste die Koordinaten des Trefferpunkts normalisieren, um die Kugeln so aussehen zu lassen. Ansonsten würden sie aussehen wie:
Wurde der Trefferpunkt normalisiert, stimmt der richtige Ansatz überein oder ist in meinem Code etwas anderes kaputt? Danke!
Anstatt den Trefferpunkt zu normalisieren, habe ich versucht, ihn in den Weltursprung zu übersetzen (als ob das Kugelzentrum dort wäre) und folgendes Ergebnis erhalten:
Ich verwende übrigens eine 256x256 Auflösung Textur.
Es ist unklar, was Sie meinen, indem Sie den Trefferpunkt "normalisieren", da es im Code, den Sie gepostet haben, nichts normalisiert, aber Sie haben erwähnt, dass Ihr Trefferpunkt im Weltbereich liegt.
Sie haben auch nicht gesagt, welches Textur-Mapping Sie implementieren möchten, aber ich nehme an, Sie möchten, dass Ihre U- und V-Texturkoordinaten den Breiten- und Längengrad auf der Kugeloberfläche darstellen.
Ihr erstes Problem besteht darin, dass die Umwandlung von kartesischen in sphärische Koordinaten erfordert, dass die Kugel im kartesischen Raum am Ursprung zentriert ist, was im Weltraum nicht stimmt. Wenn sich der Trefferpunkt im Welt-Raum befindet, müssen Sie den Weltraum-Mittelpunkt der Kugel subtrahieren, um den effektiven Trefferpunkt in lokalen Koordinaten zu erhalten. (Sie haben diesen Teil bereits herausgefunden und die Frage mit einem neuen Bild aktualisiert.)
Ihr zweites Problem ist, dass die Art, wie Sie theta
berechnen, erfordert, dass die Kugel einen Radius von 1 hat, was nicht wahr ist, selbst nachdem Sie das Zentrum der Kugel zum Ursprung bewegt haben. Denken Sie an Ihre Trigonometrie: Das Argument für acos
ist das Verhältnis der Seite eines Dreiecks zu seiner Hypotenuse und liegt immer im Bereich (-1, +1). In diesem Fall ist Ihre Y-Koordinate die Seite und der Radius der Kugel ist die Hypotenuse. Sie müssen also beim Aufruf von acos
durch den Radius der Kugel dividieren. Es ist auch eine gute Idee, den Wert auf den Bereich (-1, +1) zu beschränken, falls der Gleitkomma-Rundungsfehler etwas außerhalb liegt.
(Im Prinzip müssten Sie auch die X- und Z-Koordinaten durch den Radius teilen, aber Sie verwenden diese nur für eine inverse Tangente, und wenn Sie beide durch den Radius teilen, ändert sich ihr Quotient nicht und wird somit gewonnen ' phi
nicht ändern.)
Momentan funktionieren Ihre Sphärenschnitt- und Texturkoordinatenfunktionen im Weltall, aber Sie werden es wahrscheinlich später nützlich finden, zu implementieren Transformationsmatrizen , mit denen Sie Dinge von einem Koordinatenraum in einen anderen transformieren können. Dann können Sie Ihre Kugelfunktionen so ändern, dass sie in einem lokalen Koordinatenraum arbeiten, in dem der Mittelpunkt der Ursprung und der Radius 1 ist, und jedem Objekt eine zugehörige Transformationsmatrix zuweist, die den lokalen Koordinatenraum auf den Weltkoordinatenraum abbildet. Dies vereinfacht Ihren Strahlen- / Kugel-Schnittpunktcode und ermöglicht es Ihnen, die Ursprungssubtraktion und die Radiusdivision von GetTextureCoord
zu entfernen (da sie immer (0, 0, 0) bzw. 1 sind).
Um einen Strahl mit einem Objekt zu schneiden, verwenden Sie die Transformationsmatrix des Objekts, um den Strahl in den lokalen Koordinatenraum des Objekts zu transformieren, den Schnittpunkt zu erstellen (und dort die Texturkoordinaten zu berechnen) und dann das Ergebnis zu transformieren (zB Trefferpunkt) und Oberflächennormale) zurück zum Weltall.
Tags und Links c++ raytracing