Texturkoordinaten einer Kugel
-
Hi,
ich stehe gerade total auf dem Schlauch.
Irgendwo ist ein Zahlendreher oder ein übler Denkfehler.Ich versuche diese Textur auf eine Kugel zu mappen:
http://s7.directupload.net/images/140308/syx9uxt7.jpgDas Ergebnis sieht so aus:
http://s7.directupload.net/images/140308/9pstt7bt.jpg
Hier bitte beachten: Zur Darstellung des Problems ist die Kugel auf wenigst mögliche Eckpunkte reduziert und die Polkappen sind entfernt. Die von Hand eingezeichnete Rote Linie verdeutlicht das Problem. Der S-förmige Verlauf der Längengrade ist schlicht falsch.Um es noch etwas klarer zu machen, nur die Häflte dieser Triangles:
http://s14.directupload.net/images/140308/kkeyowzo.jpg
Wieder von Hand mit roten Linien eingezeichnet was das Problem ist. Die Längengerade sind parallel zum linken Rand der Triangles. Bei den Dreiecken die in diesem Bild nicht gerendert wurden, wären die Längengerade parallen zu den rechten Kanten, wodurch es zu diesem verzerrten S-förmigen Verlauf kommt.Ich schaue schon viel zu lange darauf und erkenne den Fehler nicht und habe gerade eine Denkblockade. Kann mir jemand aushelfen? Im folgenden der wesentliche Code, reduziert auf die Darstellung im letzten Bild.
(OpenGL in C#. Berechung der Koordinaten für einen VBO. Denkfehler vermutlich bei den Werten in texArray)
private Vector3 SphereCoords(float rad, float phi, float theta) { float y = rad * (float)(Math.Cos(Math.PI * theta)); float x = rad * (float)(Math.Sin(Math.PI * theta) * Math.Cos(2 * Math.PI * phi)); float z = rad * (float)(Math.Sin(Math.PI * theta) * Math.Sin(2 * Math.PI * phi)); return new Vector3(x, y, z); } public Sphere(float rad, int slices, int stacks) { Func<int, int, Vector3> sphere = (u, v) => SphereCoords(rad, 1.0f * u / slices, 1.0f * v / (stacks-1)); Func<int, int, uint> coord = (x, y) => (uint)(y*(slices+1) + x); int arraySize = stacks * (slices+1); Vector3[] vertArray = new Vector3[arraySize]; Vector3[] normalArray = new Vector3[arraySize]; Vector2[] texArray = new Vector2[arraySize]; List<uint> indices = new List<uint>(); for (int y = 0; y <= stacks - 1; ++y) { for (int x = 0; x <= slices; ++x) { Vector3 s = sphere(x, y); vertArray[coord(x, y)] = s; normalArray[coord(x, y)] = s; texArray[coord(x, y)] = new Vector2(1 - 1.0f * x / slices, 1.0f * y / (stacks - 1)); //nördliche polkappe //if (y == 0 && x < slices) //{ // indices.Add(coord(x, y)); // indices.Add(coord(x + 1, y + 1)); // indices.Add(coord(x, y + 1)); //} //else // mittlerer ring if (0 < y && y < stacks - 2 && x < slices) { indices.Add(coord(x, y)); indices.Add(coord(x + 1, y)); indices.Add(coord(x + 1, y + 1)); //indices.Add(coord(x, y)); //indices.Add(coord(x + 1, y + 1)); //indices.Add(coord(x, y + 1)); } //südliche polkappe //else if (y == stacks - 2 && x<slices) //{ // indices.Add(coord(x, y)); // indices.Add(coord(x + 1, y)); // indices.Add(coord(x, y + 1)); //x+1 denken //} } } vbo = new VboIndexedVertexNormalTex(vertArray, normalArray, texArray, indices.ToArray()); }
-
Sorry ich steig grad nicht wirklich durch, und hab keine Lust dafür jetzt das ganze drumherum zu schreiben dass es läuft.
Wenn du ein kompilierbares Beispiel gibst schau ich mirs morgen mal an.Warum eigentlich in dieser Zeile:
texArray[coord(x, y)] = new Vector2(1 - 1.0f * x / slices, 1.0f * y / (stacks - 1));
einmal "1 - 1.0f * x" aber "1.0f*y" ?
Müssten nicht beide Berechnungen gleich laufen ?
-
Wie du schon richtig erkannt hast liegt es an den Polygonen. Bzw. daran das Texturen auf Polygone geklatscht werden.
http://s14.directupload.net/images/140309/dxkqj6kg.jpg
Entweder du benutzt sehr viel mehr Polygonen um eine Kugel zu machen und diese Effekt wird so klein, dass man es nicht/kaum mehr wahrnimmt.
Oder du schreibst dir einen Shader der die Texturkoordinaten per Pixel berechnet.
-
-
Osbios schrieb:
Wie du schon richtig erkannt hast liegt es an den Polygonen. Bzw. daran das Texturen auf Polygone geklatscht werden.
http://s14.directupload.net/images/140309/dxkqj6kg.jpg
Entweder du benutzt sehr viel mehr Polygonen um eine Kugel zu machen und diese Effekt wird so klein, dass man es nicht/kaum mehr wahrnimmt.
Oder du schreibst dir einen Shader der die Texturkoordinaten per Pixel berechnet.
Ich verstehe ja prinzipiell auch wie dieser Effekt entsteht. Aber nur zur Gewissheit: Das Problem ist auf Vertexebene und ohne Pixelshader nicht zu beheben, sehe ich das richtig?
@DarkShadow44
Das 1 - 1.0f * x nur hat mit dem Problem nichts zu tun. Ansonsten wäre die Textur seitenverkehrt.
-
War mir erst nicht sicher, da ich noch nicht wirklich was mit Texturmapping + Perspektive gemacht habe.
Habe nun das hier gefunden/ergoogeld: http://hacksoflife.blogspot.de/2008/08/perspective-correct-texturing-in-opengl.html
Kann dazu nicht sehr viel sagen, da ich es selber noch nicht benutzt habe.