Files |  Tutorials |  Articles |  Links |  Home |  Team |  Forum |  Wiki |  Impressum

Aktuelle Zeit: Mi Jul 02, 2025 20:55

Foren-Übersicht » Programmierung » Einsteiger-Fragen
Unbeantwortete Themen | Aktive Themen



Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Autor Nachricht
 Betreff des Beitrags: 3D-Landkarte zeichnen
BeitragVerfasst: Di Apr 23, 2013 19:33 
Offline
DGL Member

Registriert: Di Apr 02, 2013 14:54
Beiträge: 8
Programmiersprache: C#
Hallo liebes Forum,
ich möchte gerne eine 3D-Landkarte zeichnen. Dazu habe ich eine Datei mit Koordinaten und eine Datei mit Objekten, die auf der Karte sind.

Ich bin jetzt so weit, dass ich die Karte zeichne und Objekte auf den Dreiecken der Map zeichne (ich färbe die Dreiecke einfach...).

Mein Problem: die Geschwindigkeit und die Genauigkeit.

Insgesamt zeichne ich nämlich 2048x2048 Quads. Wenn ich statt jeden Punkt zu zeichnen nur jeden... 2ten oder 3ten, ... Punkt zeichne, dann wird das Objekte anzeigen seehr ungenau.
Jetzt habe ich mir gedacht ich zeichne meine Objekte einfach in eine riesige Textur und klatsche sie auf die Dreiecke... Aber ich bin mir nicht sicher... Sollte man beispielsweise eine 16k mal 16k Textur anlegen?

Ich möchte außerdem dieses LOD http://wiki.delphigl.com/index.php/Tutorial_Terrain3 verwenden. Allerdings bin ich mir nicht sicher, wie ich die Elemente überhaupt zeichne? Ich habe es mal ungefähr so probiert:

Code:
  1. private void DrawMapParts(float x, float y, int size)
  2.         {
  3.             if (size == 1)
  4.             {
  5.                 //Zeichne TriangleFan
  6.                 GL.Begin(OpenGL.BeginMode.TriangleFan);
  7.                 {
  8.                     GL.Vertex3(x - 1f, y - 1f, 0.0f);
  9.                     GL.Vertex3(x + 1f, y - 1f, 0.0f);
  10.                     GL.Vertex3(x + 1f, y + 1f, 0.0f);
  11.                     GL.Vertex3(x - 1f, y + 1f, 0.0f);
  12.                 }
  13.                 GL.End();
  14.             }
  15.             else
  16.             {
  17.                 //Unterteile in 4 kleinere Ecken
  18.                 DrawMapParts(x / 2.0f + size / 2.0f, y / 2.0f + size / 2.0f, size / 2);
  19.                 DrawMapParts(x / 2.0f + size / 2.0f, y / 2.0f - size / 2.0f, size / 2);
  20.                 DrawMapParts(x / 2.0f - size / 2.0f, y / 2.0f + size / 2.0f, size / 2);
  21.                 DrawMapParts(x / 2.0f - size / 2.0f, y / 2.0f - size / 2.0f, size / 2);
  22.             }
  23.  
  24.         }


Liefert bei mir unglaublich schlechte Ergebnisse: bei einem 9x9-Feld erreiche ich kaum 10 FPS...

Könnt ihr mir helfen?

Grüße


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: 3D-Landkarte zeichnen
BeitragVerfasst: Di Apr 23, 2013 21:57 
Offline
DGL Member
Benutzeravatar

Registriert: Do Okt 16, 2008 13:18
Beiträge: 252
Hallo,
so wie ich dein Problem sehe könnten dir eventuell VBOs (Tutorial_Vertexbufferobject) helfen deine Frameraten zu normalisieren. Ein großes Problem dürfte die Anzahl der glBegin- und glEnd-Befehle sein, welche du im Moment für jeden Frame an die Grafikkarte schickst. Bei VBOs könnten (je nach Situation, zB. wenn die Landschaft statisch und nicht stark unterteilt ist) schon wenige oder sogar nur ein Draw-Call ausreichen, da die Daten schon auf der Grafikkarte liegen.
Edit: Es macht, während des Zeichnens, ab einer gewissen Untergrenze von Vertices Sinn diese nicht mehr weiter zu unterteilen sondern einfach rendern zu lassen, da man sich sonst zu lange an jedem Dreieck aufhält.

Eine RGB-Float-Textur mit 16.000 Pixeln Größe würde 3GB belegen und dürfte damit zu groß für die meisten Grafikkarten sein. Wenn ich es richtig sehe, brauchst du im Moment für jedes Dreieck nur eine Information welche die Farbe bestimmt. Die könntest du direkt in das VBO packen, falls sich die Farbe nicht ändert. Wenn du die Farben verändern willst kannst du die Farben auch in eine Textur mit den Maßen der Kartenpunkte schreiben und mit Texturierung jedem Dreieck einen Farb-Pixel aus der Textur zuweisen.

Grüße
Mori

_________________
You even trying ...

Website: http://rise-of-light.de/


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: 3D-Landkarte zeichnen
BeitragVerfasst: Mi Apr 24, 2013 06:49 
Offline
DGL Member
Benutzeravatar

Registriert: Do Dez 29, 2005 12:28
Beiträge: 2249
Wohnort: Düsseldorf
Programmiersprache: C++, C#, Java
Ggf. reicht es zunächst mal glBegin- und glEnd aus deinem DrawMapParts heraus zu nehmen und statt TriangleFan einfach Quads zu rendern. Aber auf lange sicht ist ein VBO der korrekte weg.

Allerdings scheint mir deine "3D-Landkarte" einfach flach zu sein. Das könntest du auch deutlich einfacher haben. Wenn es eine Heightmap werden soll, mach es mit Shadern:
http://wiki.delphigl.com/index.php/Shad ... ap-Terrain

Üblicherweise benutzt man keine große Textur für ein Terrain. Schau dir mal das hier an:
http://wiki.delphigl.com/index.php/shader_Terrain_GPU4
Da werden drei Texturlayer (Fels, Sand, etc.) gekachelt und über eine Kontrolltextur gesteuert.

Wenn du tatsächlich eine große Textur benötigst kann eine Megatexture bzw. VirtualTexturing eine Option sein. Einfach googlen. Damit sind Texturgrößen von 131072 x 131072 und mehr machbar. Bei meiner Diplomarbeit hatte ich mit dieser Technik (die ich noch etwas erweitern musste) 15.9 GB Luftbild-Daten verwaltet. Die Implementierung ist allerdings nicht einfach.

_________________
Yeah! :mrgreen:


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: 3D-Landkarte zeichnen
BeitragVerfasst: Mi Apr 24, 2013 22:21 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Eine 16k x 16k Textur kann OpenGL garnicht fassen und wird dir auf jedenfall ein Skalierungsproblem vor die Füße legen.
Wie Coolcat schon erwähnt hat sind sollten streaming Techniken wie Virtual Texture verwendet werden.
Man hat eine logisch sehr große Textur und zieht sich die benötigten Daten hinaus, die man für den kommenden Frame benötigt.
Dazu zählen in der Regel Höhendaten, Texturen(Diffuse, Normal, Spec, Splatmap, Wang-Tiles oder was auch immer) und Gebietsspezifische Informationen(z.B. Atmosphäreninformationen, Assets).
Man kann da auch Prozedural ran gehen und sich ein bisschen das Leben einfacher machen aber auch restriktiver.
Du kannst z.B. deine Welt in ein Quadtree projezieren, ja Kugel passt auf Quadrat.
Nun kannst du deine 3D Position zu einer 2D Position projizieren und entsprechend die vorher genannten Daten als filenames kodieren z.B.
color_x009_y003_lod4.jpg oder assets_x009_y003_lod4.xml.
Das funktioniert recht gut, bis zu einigen hundert files, wenn dann in tausende Files Bereich kommst wird es kritisch, weil Windows NTFS das garnicht ab kann und dann kannst du einfach alles in ein tar packen, nicht komprimieren sondern Speichern.
Das sorgt dafür, dass die operation nur ein bruchteil einer Sekunde braucht, obwohl du mehrere GB transportierst, DMA und großen HDD Caches sei dank.
Das wäre dann ein Virtuell file system und umgeht die Problematik von ein komplexeren Virtuell Texture, was aus Vogelperspektive recht ähnlich ist.

Ich hab auf Arbeit ein Virtuell Texture System implementiert, welches aktuell mit ~7GB Raw Bildaten hantiert und ~100MB komprimiert.
Da ich aber für ne Mobile Company arbeite, muss die file streambar, patchbar sein und kleiner Download gewichtet mehr als Qualität.
In meiner Bachelor Arbeit hab ich damals richtiges Virtual Texturing implementiert, mit Renderoutput analyse und co, wie es heute ID Tech 5 macht und das braucht mindestens DX10 Hardware bzw. ne menge OpenGL Extensions, ist ziemlich komplex, wegen Colorbleeding, Mipmapverwaltung und Bildanalyse.
edit:
Es geht natürlich mit DX9c und entsprechender OpenGL Version aber mit mindestens 1 Frame versatzt, bzw. einer CPU limitierten Framerate.
Man muss auf so alten Systemen, ein Renderpass machen, welcher die ChunkIDs in eine Textur rendert und dann in den Arbeitsspeicher transportiert, von der CPU analysiert, entsprechende Chunks geladen, in den Atlas kopiert und die lookup map geupdated werden.


Da ist der Kachelansatz mit seinen eigenen Daten wesentlich einfacher und kann sich das alles sparen.
Denn das richtige Virtual Texture hat als Hauptfeature, dass man nur ein fixen Texturspeicher braucht, egal wieviel Texturdaten in dem Terrain stecken.

Ein Rat den ich geben kann, breche deine Probleme immer wieder auf Texturen oder VBO runter.

Als kleines Beispiel kann ich Splat/Blend-maps nennen, diese benötigen recht kostenintensive Shader, beschränken dich auf 5 Texturen und müssen dann darüber in mehreren Passes gerendert werden.
Statt dessen ist es besser die in ein Preprozess zu rendern, egal ob auf der Zielkiste per CPU/GPU oder schon vor der Auslieferung.
Wang-Tiles haben das gleiche Problem wird aber beherrschbar, wenn man es nicht versucht in die Shaderpipeline zu pressen.
Ein recht guter Weg ist hierfür die Splat/Blend-maps und die tilesets verpacken und dann bei bedarf für eine Terrainkachel on the fly zu bauen, in der Virtuellen Textur/Virtuel filesystem zu hinterlegen und dann asynchron als Textur zu laden.
Da kann man dann auch Coole Hacks bauen, die so garnicht denkbar wären, weil die nie auf der GPU realisierbar wären, sei es wegen Performance oder Komplexität.

Wenn du anfängst ein Terrain renderer zu bauen, hab keine Angst, dass am Anfang die FPS sehr niedrig sind.
Man kann ne menge optimieren aber das sollte man erst machen, wenn es notwendig wird.
Das fängt mit der Art von Primitiven an(Triangles < Quads < TriangleStripes) geht über das Datenformat(32Byte als maximales Datenchunk für ein Vertex, ABGR < BGR < DXT5 < DXT1 Texturen), Shader, Drawcalls, Z-Prepass und so weiter.
Je nach Hardware kann man dann auch Geometry und Tesselierungs Unit aus nutzten.

Es geht aber auch ohne, wir rendern ein ganzen fiktiven Kontinent mit aktuell 16k x 32k Texturdaten und 8k x 16k Höhendaten in einem Deferred Renderer mit Shader Model 2(DX9b) und läuft auf einer GF240 flüssig.

Also wenn wir dir fancy Techniken wie Geometry Shader um die Ohren hauen zeigen wir nur den neusten Stand der Möglichkeiten auf, es geht natürlich auch mit alter Hardwware und Techniken sehr gut.

P.S. Gott würde ich gerne gegen Shader Modell 5 Programmieren ^^

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: 3D-Landkarte zeichnen
BeitragVerfasst: Sa Apr 27, 2013 11:07 
Offline
DGL Member

Registriert: Di Apr 02, 2013 14:54
Beiträge: 8
Programmiersprache: C#
Hallo,

Danke für eure Antworten. Ich bin aber jetzt irgendwie verwirrt... Also um die Render-Geschwindigkeit zu erhöhen, fallen mir jetzt folgende Techniken ein:

- LOD (mit zunehmender Entfernung weniger Dreiecke zeichnen)
- Continuous Level of Detail für Heightmaps (Optimierung, Verringerung Dreiecke)
- Octree + Frustum Culling
- VBOs
(- Shader)

Wenn ich VBOs verwende, dann male ich die Karte statisch. Aber wenn ich dann LOD einbaue, muss ich die Dreiecke immer wieder je nach Detailgrad anpassen und... ja... die Daten immer wieder auf die Grafikkarte schieben. Kann ich dann überhaupt VBOs benutzen bzw. bringen sie mir dann noch einen Geschwindigkeitsvorteil?

Bei dem "Continuous Level of Detail für Heightmaps" hab ich gedacht, ich muss TriangleFans nehmen, um Löcher zu vermeiden? Außerdem verfolgt das Tutorial einen rekursiven Mechanismus und wenn ich nicht alle Punkte zum Anfang zeichnen will, muss ich doch einen neuen Draw-Call verwenden, oder?

Eine Heightmap per Shader zu zeichnen möchte ich eigentlich noch nicht probieren. Ich möchte erst einmal meine Kenntnisse in OpenGL verbessern, bevor ich dann später in GLSL einsteige.

Wegen der Texturen: ich habe mir das so gedacht, dass ich zuerst eine 2048x2048 Textur für die Karte nehme und wenn ich näher komme, nehme ich weitere 2048x2048 Texturen. Da würde ich das mit Virtual Texturing umgehen.


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: 3D-Landkarte zeichnen
BeitragVerfasst: Sa Apr 27, 2013 11:58 
Offline
DGL Member
Benutzeravatar

Registriert: Do Sep 02, 2004 19:42
Beiträge: 4158
Programmiersprache: FreePascal, C++
Also dynamisches LOD mit VBOs ist haarig. Hab ich mal probiert, ist aber extrem langsam geworden. Also vorallem ist die berechnung auch für große Terrains nicht mehr sonderlich schnell, und so gut sah's auch nicht aus. Man hat halt schon gemerkt, wenn sich die Kamera bewegt hat und so.

Ich habe dazu neulich schonmal was geschrieben. cLOD kann man auch ohne triangle fans bauen, wenn man's richtig macht. Der Source ist im obigen Link verlinkt ;).

grüße

_________________
If you find any deadlinks, please send me a notification – Wenn du tote Links findest, sende mir eine Benachrichtigung.
current projects: ManiacLab; aioxmpp
zombofant networkmy photostream
„Writing code is like writing poetry“ - source unknown


„Give a man a fish, and you feed him for a day. Teach a man to fish and you feed him for a lifetime. “ ~ A Chinese Proverb


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: 3D-Landkarte zeichnen
BeitragVerfasst: So Apr 28, 2013 10:16 
Offline
DGL Member

Registriert: Di Aug 21, 2012 19:31
Beiträge: 173
Programmiersprache: C#
Das kann ich bestätigen ;)

Habe kein zufriedenstellendes Ergebnis erzielt.

Grüße!

_________________
ack nack nack nack nack


Nach oben
 Profil  
Mit Zitat antworten  
 Betreff des Beitrags: Re: 3D-Landkarte zeichnen
BeitragVerfasst: So Apr 28, 2013 11:38 
Offline
DGL Member
Benutzeravatar

Registriert: Di Mai 18, 2004 16:45
Beiträge: 2623
Wohnort: Berlin
Programmiersprache: Go, C/C++
Wenn du das VBO veränderst, dann macht es kein Sinn.
Da solltest du auf eine Variante setzten, die ohne auskommt.
Ich kann da folgende cdlod technik empfehlen.
Bau die einzelnen LOD stufen von einem Chunk, indem du immer jedes 2. Vertex auf X und Z Achse entfernst.
Die Chunks sind alle gleich groß nur die Vertexahl halbiert sich.
Dann machst du für die Vertices, die in der nächsten Stufe weg fallen ein Raycast auf die Y-Achse und suchst den Schnittpunkt des nächsten LOD.
Die Information speicherst du mit in deine Vertexdaten, z.B. in UV.w oder Position.w.
Im Shader errechnest du nun anhand des Tiefenpuffers und der selber definierten distanz das LOD Level und nimmst den Nachkomma wert als Blendwert für eine Lineare Interpolation zwischen vertex position und vertex position, wo y durch den w wert ersetzt wurde.
So morphen die Vertices immer in den niedere LOD und man sieht kein ploppen und in der Regel auch kein morphen.
Welche LOD Stufe in den VBO muss, kannst du anhand der Kamera Position und der Distanz errechnen.

Der Vorteil zu den alternativen cdlod verfahren ist, dass dieser nur eine Komponente braucht und nicht ein morph Vektor.
Man sollte seine Vertexdaten nie über 32Byte(sonnst bricht der Vertexcache zusammen) kommen lassen und da ist es mit einem float(höhe) einfacher als mit 3 floats(nächster nachtbar Punkt) ist, empfehle ich die cdlod variante.
Ich finde leider das passende Paper nicht, daher hab ich es erklärt, wie es geht.

Der Nachteil dieser Technik ist, dass man immer nur eine LOD-Stufe zum Nachbar runter gehen kann, nie 2 oder mehr.
So hat man recht viele Triangle auf dem Bild aber das ist echt verkraftbar.

_________________
"Wer die Freiheit aufgibt um Sicherheit zu gewinnen, der wird am Ende beides verlieren"
Benjamin Franklin

Projekte: https://github.com/tak2004


Nach oben
 Profil  
Mit Zitat antworten  
Beiträge der letzten Zeit anzeigen:  Sortiere nach  
Ein neues Thema erstellen Auf das Thema antworten  [ 8 Beiträge ] 
Foren-Übersicht » Programmierung » Einsteiger-Fragen


Wer ist online?

Mitglieder in diesem Forum: 0 Mitglieder und 12 Gäste


Du darfst keine neuen Themen in diesem Forum erstellen.
Du darfst keine Antworten zu Themen in diesem Forum erstellen.
Du darfst deine Beiträge in diesem Forum nicht ändern.
Du darfst deine Beiträge in diesem Forum nicht löschen.
Du darfst keine Dateianhänge in diesem Forum erstellen.

Suche nach:
Gehe zu:  
  Powered by phpBB® Forum Software © phpBB Group
Deutsche Übersetzung durch phpBB.de
[ Time : 0.007s | 14 Queries | GZIP : On ]