Generierung von Planetentexturen - Texturkoordinaten

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
Benutzeravatar
joeydee
Establishment
Beiträge: 1085
Registriert: 23.04.2003, 15:29
Kontaktdaten:

Re: Showroom - Aktuelle Arbeiten und Projekte

Beitrag von joeydee »

Despotist hat geschrieben: 1. weniger Verzerrung, nicht "keine".
2. geht es hier um die Repräsentation echter Daten, bei mir um die Erzeugung künstlicher Daten.
3. das Problem mit dem Aufbringen der Textur auf eine Lat/Long Kugel bleibt bestehen.
4. Du sprichst (wenn ich dich richtig verstehe) davon die Werte der Textur auf ein Mesh (Kugel) zu bringen. Bei mir gehts ja andersrum und ich berechne die Noisewerte an der Position der Pixel der Textur und mappe diese dann auf die Kugel. Dass das zu Artefakten und Anomalien an den Polen führt ist klar liegt aber mehr an dem generellen Problem 2d Flächen auf 3d Körper zu bringen und umgekehrt.
5. das "Framework" ist so gestaltet dass sich der Nutzer die Daten für einen beliebigen rechteckigen Ausschnitt holen kann und was er dann damit anstellt bleibt ihm überlassen. Das mappen auf eine Lat/Long Kugel ist also nur mein stümperhafter Versuch einer Visualisierung. Genausogut kann man es auf alles andere mappen.
1. Keine ist auch unmöglich, aber Krishty hat schon recht: mit einem Cubemesh als Basis ist es viel weniger Verzerrung, da sie sich auf 8 statt nur 2 Pole verteilt. D.h. lange dünne Dreiecke entstehen erst gar nicht.
2. Tut nichts zur Sache woher die Daten kommen. Im Gegenteil: reale Texturen für Kugeln (Planeten) findet man sogar eher als lat/long statt als Cubemap.
3. Nein, das Problem ist damit (deutlich besser) gelöst. Du musst natürlich auch das Mesh austauschen (welches Krishty oben gepostet hat), nicht nur das Mapping.
4. Das geht genauso: man berechnet den Wert an einer Texelposition. Um die 3D-Position eines Cubemaptexels zu rekonstruieren ist nichtmal Trigonometrie erforderlich. 3D-Noise auf die Position anwenden und Texelfarbe setzen ist dasselbe. Das Berechnen eines Noisewertes im Raum sollte jedenfalls unabhängig vom Mappingverfahren sein, falls nicht, rate ich dir dringend, auch das zu ändern.
4b. siehe 1.
5. Wenn es dir zur Visualisierung reicht, ist das doch ok. Wenn du später aber eine höhere, evtl. dynamische Tesselierung (LOD) anstrebst, wirds mit einer Cubemap und dem passenden Mesh aber deutlich einfacher und besser.
Despotist
Establishment
Beiträge: 394
Registriert: 19.02.2008, 16:33

Re: Showroom - Aktuelle Arbeiten und Projekte

Beitrag von Despotist »

Wie gesagt habe ich Lat/Long gewählt da ich die so erstellte Textur gleich als 2d Karte verwenden kann wo der User auch Punkte auswählen soll so dass ich deren Position (Lat/Long, 3d Raum) auch direkt kenne. Die Kartendarstellung fällt ja für Cubemaps flach da sie keine gewohnte Orientierung ermöglichen (siehe KrishtyÄs Mondbeispiel). Es wird also wahrscheinlich eh auf eine Mischung der Verfahren hinauslaufen eben für die verschiedenen Zwecke/Darstellungsformen.
joeydee hat geschrieben: Das Berechnen eines Noisewertes im Raum sollte jedenfalls unabhängig vom Mappingverfahren sein, falls nicht, rate ich dir dringend, auch das zu ändern.
Der Simplexnoise wird mit 3d Koordinaten aufgerufen ist also entsprechend flexibel. Für die LatLongtextur werden die Positionen der Pixel über eine Umrechung in sphärische Koordinaten ermittelt welche dann in 3d Koordinaten transformiert werden.
joeydee hat geschrieben: Wenn es dir zur Visualisierung reicht, ist das doch ok. Wenn du später aber eine höhere, evtl. dynamische Tesselierung (LOD) anstrebst, wirds mit einer Cubemap und dem passenden Mesh aber deutlich einfacher und besser.
Da gleich noch eine Frage dazu: Wenn ich die Cubetextur verwende lohnt sich das doch nur wenn ich wirklich die gesamte Kugel abdecke. Wenn ich zb reinzoomen will auf immer kleinere Ausschnitte brauch ich ja den ganzen Rest nicht mehr. Die räumliche Auflösung muss sich aber erhöhen um mehr Detail abzubilden. Wie muss ich mir das in der Technik die von euch vorgeschlagen wird vorstellen? Ich kann ja die Auflösung der Textur nicht beliebig vergrößern (Hardware).
Bei der LatLongtextur sage ich einfach nimm statt den gesamten Planeten nur noch einen Teil von x1,y, bis x2,y2 und berechne die Zwischenpunkte in derselben Auflösung wie vorher (die reale Auflösung bleibt gleich aber die räumliche Auflösung erhöht sich beim reinzoomen).
Was mich auch ein bisschen wurmt ist die "Platzverschwendung" in der Cubemaptextur da ja die Hälfte der Fläche nicht genutzt wird. Oder könnte man das auch vermeiden indem man die Flächen unzusammenhängend speichert und mit den Seiten des Würfels auf den jeweiligen Bereich in der Textur verweist? Das sollte ja relativ einfach gehen wenn die Koordinaten mitgespeichert werden. Oder werden die nur berechnet?
Benutzeravatar
Krishty
Establishment
Beiträge: 8305
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

Re: Showroom - Aktuelle Arbeiten und Projekte

Beitrag von Krishty »

Despotist hat geschrieben:Was mich auch ein bisschen wurmt ist die "Platzverschwendung" in der Cubemaptextur da ja die Hälfte der Fläche nicht genutzt wird. Oder könnte man das auch vermeiden indem man die Flächen unzusammenhängend speichert und mit den Seiten des Würfels auf den jeweiligen Bereich in der Textur verweist?
Cubemaps werden üblicherweise nur zu Darstellungszwecken zu der Form abgerollt, die ich gepostet habe. Intern speichert man sie als ein Array von sechs quadratischen Texturen bzw. einen vertikalen Stapel in 1×6-Seitenverhältnis, siehe wieder Anhang für das Mondbeispiel.

Ich habe gerade nachgerechnet, und die minimale räumliche Auflösung von Texture Cubes ist bei selber Pixelzahl tatsächlich 10 % geringer (also die Distanz, die Texel maximal weit im 3D-Raum auseinanderliegen, 10 % größer):

Gehen wir davon aus, dass du die Erde mit ihren idealisierten 40.000 km Umfang auf 100 km genau darstellen willst, Texel also nicht größer als 100×100 km sein dürfen. Eine geographische Textur wäre dann (40.000 km ÷ 100 km) × (20.000 km ÷ 100 km) = 400×200 = 80.000 Pixel groß.

Von diesen 80.000 Pixeln kannst du theoretisch sechs Seiten eines Texture Cubes mit je 115,47 Pixeln Seitenlänge erzeugen. Du hast dann einen Würfel, der auf jeder Seitenlänge 115 Mal unterteilt ist. Dabei haben die vier Texel um die je sechs Würfelflächenmittelpunkte minimale Winkelauflösung, d.h. maximale räumliche Entfernung auf der Kugel. Und die überspannt einen Winkel von atan(1 ÷ (115,47 ÷ 2)) auf der Kugel, also 0,99635° von 360°, was 110,7 von 40.000 km entspricht.

Natürlich gesetzt dem Fall, dass ich da jetzt keinen Denkfehler drin habe (wenn der liebe Gott gewollt hätte, dass ich Mathe kann, hätte er mir Solarzellen auf die Stirn gepappt).

Das entsetzt mich nun selber ein bisschen, weil ich eher 10 % höhere Auflösung erwartet hätte, da nicht so viele Texel in die Pole abfließen. Die Masse von acht Polen gegenüber zwei bei geographischen Koordinaten macht’s aber.

Man kann Cubemaps tunen, damit sie überall nahezu gleichmäßige räumliche Auflösung haben. Theoretisch lassen sich dann 87 km Auflösung erreichen, aber dann muss man bei jeder Koordinatenumrechnung den Tangens ausrechnen, und das geht massiv auf die Leistung.
Dateianhänge
Moon albedo (stacked).png
Zuletzt geändert von Krishty am 31.05.2011, 12:20, insgesamt 1-mal geändert.
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
Despotist
Establishment
Beiträge: 394
Registriert: 19.02.2008, 16:33

Re: Showroom - Aktuelle Arbeiten und Projekte

Beitrag von Despotist »

Krishty hat geschrieben: Cubemaps werden üblicherweise nur zu Darstellungszwecken zu der Form abgerollt, die ich gepostet habe. Intern speichert man sie als ein Array von sechs quadratischen Texturen bzw. einen vertikalen Stapel in 1×6-Seitenverhältnis, siehe wieder Anhang für das Mondbeispiel.
Ja so hatte ich mir das vorgestellt. Dann ist ja alles ok.
Benutzeravatar
joeydee
Establishment
Beiträge: 1085
Registriert: 23.04.2003, 15:29
Kontaktdaten:

Re: Showroom - Aktuelle Arbeiten und Projekte

Beitrag von joeydee »

Ja, man verwaltet intern 6 einzelne Texturen. Je eine für ein gewölbtes Quad, welche zusammen eine Kugel ergeben. Die Quads kannst du dann leichter und sinnvoller unterteilen (Quadtree z.B.) als eine lat/long-Map. Und natürlich ebenso Ausschnitte in höherer Auflösung berechnen etc.
Das einfachste Rendern per Shader geschieht dann so: du lädst die Texturen als eine Cubemap hoch und renderst dein Mesh per Cubemap-Lookup. Dazu brauchst du nichtmal Texturkoordinaten im Stream.

Noch ein wenig Mathe from Scratch hierzu, ich hoffe es sind keine groben Fehler drin, aber das Prinzip sollte klar werden:
Das Vorzeichen und der maximale absolute Wert der Koordinatenkomponenten x,y,z eines Vektors verraten, welche Textur zu diesem Punkt gehört. Ist z.B. abs(x) der größte Wert gegenüber abs(y) und abs(z), und ist x<0, liegt dieser Punkt auf der linken Fläche.
alle Werte durch abs(x) teilen, und du hast mit y und z die normalisierte Texturkoordinate des Punktes, gesehen aus der Mitte der Textur mit einer Kantenlänge von 2, das musst du noch auf übliche Texturkoordinaten kompensieren.
Also z.B. (-5,3,1) heißt linke Fläche, (3/5*0.5+0.5, 1/5*0.5+0.5) sind die Texturkoordinaten auf die dieser Vektor auf die linke Fläche zeigt.
Umgekehrt gehts natürlich auch, also Texel (0.4/0.7) der linken Textur in einen Vektor umrechnen: x=-1, y=(0.4-0.5)*2=0.2, z=(0.7-0.5)*2. Den Vektor dann noch normalisieren und mit dem Radius multiplizieren, damit er auf der Kugel liegt.

@Mods: ich denke auch, diese Diskussion sollte evtl. in einen eigenen Thread getrennt werden.
Benutzeravatar
Chromanoid
Moderator
Beiträge: 4272
Registriert: 16.10.2002, 19:39
Echter Name: Christian Kulenkampff
Wohnort: Lüneburg

Re: Generierung von Planetentexturen - Texturkoordinaten

Beitrag von Chromanoid »

Antworten