Erstellen eines gekrümmten Netzes auf der Innenseite der Kugel basierend auf Texturbildkoordinaten

8

In Blender habe ich eine Kugel mit einer Panorama-Textur auf der Innenseite erstellt. Ich habe auch manuell ein ebenes Netz erstellt (gebogen, um der Größe der Kugel zu entsprechen), das sich an der Innenwand befindet, wo ich eine andere Textur zeichnen kann.

Das ist großartig, aber ich möchte die manuelle Arbeit wirklich reduzieren und einige dieser Arbeiten in einem Skript ausführen - beispielsweise eine Variable für das Panoramabild und die Koordinaten des Bereichs auf dem Foto, den ich durch einen neuen ersetzen möchte Gittergewebe.

Der schwierigste Teil dabei ist die Erstellung eines gekrümmten Netzes im Code, das an der Innenwand einer Kugel sitzen kann.

Kann mich jemand in die richtige Richtung weisen?

user5025
quelle
Können Sie näher erläutern, was mit weniger Aufwand geschehen soll? Erläutern Sie Ihre aktuelle Methode und Ihr Endergebnis genauer?
Seth Battin
Warum müssen diese beiden Netze interagieren? Könnten Sie einfach Größe und Koordinaten für das innere Netz angeben und es zeichnen, wo immer es sein muss? Warum muss es in Bezug auf die äußere Sphäre spezifiziert werden?
Seth Battin
Ich möchte in der Lage sein, ein gleichwinkliges Bild auf der Innenseite einer Kugel abzubilden und rechteckige Bilderrahmen (im Bild) mit dynamischen Bildern zu versehen. Ich möchte jedoch nicht jedes Mal, wenn ich ein neues gleichwinkliges Bild einführen möchte, alles von Grund auf neu erstellen. Um dies zu vereinfachen, möchte ich das abgeflachte Bild aufnehmen und etwas wie Photoshop verwenden, um das zu finden xy-Koordinaten eines Bilderrahmens und ein neues Netz, das auf die Kugel geschrumpft ist, die diesen 2d-Koordinaten entspricht.
user5025
Sie wissen, dass Unity Skyboxes unterstützt? Es klingt so, als ob Sie das erreichen wollen.
MichaelHouse
Ich kenne Skyboxes, aber es löst mein Problem leider nicht. Ich brauche eine Möglichkeit, ein gekrümmtes Netz zu erstellen (das perfekt auf der Innenseite einer Kugel sitzt), basierend auf den Koordinaten eines Bilderrahmens in einem gleichwinkligen Bild.
user5025

Antworten:

0

Was Sie erreichen wollen, scheint sehr eng damit verbunden zu sein:

Analog zu sphärischen Koordinaten in n-Dimensionen

In Ihrem Fall in zwei Dimensionen verwenden Sie einfach diese Formel, um die Eckpunkte des Rechtecks ​​abzubilden, das Sie auf Ihrer Kugel haben (hoffen wir, dass es unterteilt ist) (vergessen Sie nicht, irgendwo mit dem halben Durchmesser zu multiplizieren. Nur Mathematiker leben auf einer Einheitskugel, alle anderen anständige Leute benutzen Durchmesser ...)

EDIT: Da dies alles etwas vage ist, gebe ich einige weitere Einblicke. Was Sie von dieser Formel benötigen, um verwendet zu werden:

x = r*sinθ*cosφ
y = r*sinθ*sinφ
z = r*cosθ

θ und φ sind die sphärischen Koordinaten, nach denen Sie suchen (Breite und Länge), um sie zu erhalten. Nehmen Sie die x / y-Koordinaten der Punkte auf einem Teil des Panoramabilds als solche:

public Void getPointPosOnSphere(float Longitude,float Latitude,float r) {
    x = r*Mathf.sin(Longitude)*Mathf.cos(Latitude);
    y = r*Mathf.sin(Longitude)*Mathf.sin(Latitude);
    z = r*Mathf.cos(Longitude);
    return new Vector3(x,y,z);
}

//here you could have a for loop iterating through points of your rectangle for each
//point you'd have associated a map coordinate :
Vector3 pointSpacePos = getPointPosOnSphere(pointCoordY,pointCoordX,HalfDiamater);
//End of the for loop

Dann würden Sie Ihr Quad auf einer Kugel abbilden lassen, basierend auf seiner xy-Position auf einem 2D-Koordinatensystem, das gemäß der Kugelabbildung in die 3D-Position auf dem Raum übersetzt wird.

EDIT: Ich habe gerade eine Idee, um weiter zu gehen, könnten Sie die Koordinaten der Ebene auf der Kugel mit UV-Werten als solchen kapseln:

for(int i = 0;i < vertices.Length; i++) {
    vertices[i] = getPointPosOnSphere(UV[i].y,UV[i].x,HalfDiamater);
}

Dort können Sie die Quad-Position in Ihrer bevorzugten 3D-Software (oder sogar durch Code durch Einheit) verwalten, indem Sie einfach UV-Werte zuweisen (wenn auf beiden Achsen 0 bis 1 liegt, wird Quad um die Kugel gewickelt).

WARNUNG: Für die Verwendung von UV-Strahlen müssen Sie eine Umrechnung von Bogenmaß in Grad durchführen. (da UV 0 zu 1 ist)

Géry Arduino
quelle
0

Die Antwort von Géry Arduino oben hat mich in die richtige Richtung gelenkt, aber ich möchte hier einige Dinge hinzufügen.

1) Das Folgen funktioniert aufgrund von Unterschieden im Koordinatensystem nicht in Einheit

    return new Vector3(x,y,z); 

Ändern Sie dies in

    return new Vector3(x,z,y);

2) Der Eingabebereich der in der Methodensignatur definierten Long- und Lat-Werte war mir nicht klar

     public Void getPointPosOnSphere(float Longitude,float Latitude,float r)

Sowohl der Längen- als auch der Breitengrad sollten im Bogenmaß angegeben werden. Ihre Reichweite ist wie folgt

     Longitude: 0°-180° (0 - π)
     Latitude: 0°-360° (0 - 2π)
Snakebyte
quelle