auf Anregung eines netten Users auf Golem.de (viele Grüße :) ) wollte ich mich hier anmelden und nach dem Stöbern aus eigenem Interesse an der Materie auch mein kleines (Hobby-)Projekt vorstellen.
Es handelt sich um die Erzeugung eines weitestgehend prozeduralem Universum, in welchem der betrachter erstmal ohne Spielgerüst drumherum sich frei bewegen können soll. Ggf. würde ich gerne später Netzcode drum herum schreiben sodaß eine gewisse Interaktion über Netz mit zwei oder mehreren Teilnehmern möglich ist, aber das käme erst später, da ich mit dieser Materie überhaupt noch nicht vertraut bin. Im Moment geht es mir erstmal darum selbst hinzuzulernen, da ich mich mit der Materie Programmierung in 3D noch nicht allzulange beschäftige. In erster Linie gehts also darum Spaß zu haben, was zu lernen, und das Gehirn fitt zu halten. ;-)
Projekt: Prozedurales Universum
Ziel: Rendern eines (verkleinerten) Universums, in welcher der Betrachter alle Objekte ansteuern kann die er sieht (d.h. weitestgehend verzicht auf Skyboxen o.ä.).
- Das Universum soll eine gewisse Anzahl an Planeten/Objekten beinhalten, weit entfernt von der echten Anzahl von Objekten im Universum, aber soviel um einigermaßen glaubhaft zu sein.
- Die Planeten sollen bereisbar sein. Detailgenauigkeit der Oberfläche mindestens ein Triangle pro Kilometer, gerne würde ich irgendwo in den Meterbereich kommen.
- Nebel, die keine bloße Textur sind sondern eine gewisse "Voluminität" darstellen.
- Weitere Objekte: Gasplaneten, Sonnen, Schwarze Löcher
- Prozedurale Elemente (bis jetzt geplant): Planetennamen, Planetenpositionen, Planetenoberfläche (Perlin Noise + Heightmap), Nebelstuktur
Zum Stand, ich hatte begonnen das Programm in Axiom3D und C# zu schreiben, und bis zu dem Punkt gearbeitet in welchem ich auf Basis einer XML Struktur (in welcher ich die prozedural ermittelte Planetenkonfiguration ablege) ein solares System mit ca. 50.000 Objekten generiert habe, die Sonnen mittels Particle-Effekt in Ogre und die Planetenoberfläche mittels PerlinNoise + Heightmap Kombination generiert habe. Sowie ein eigenes LOD ich die sichtbaren Objekte in einem separaten Thread kontinuierlich parse und weit entfernte Objekte als Point Sprite gezeichnet wurden, in einem Zwischenbereich zur Kameraposition Meshes generiert wurden mit unterschiedlichem Detailgrad, und ab Orbitdistanz der Planet einer Liste "Aktiver Planeten" hinzugefügt wurde, wo die Planeten bevorzugt berechnet werden und ich auf HorizonCulling umstelle.
Generell waren die Planeten als Cubespheres umgesetzt, mit einer dynamischen Anzahl einzelner Chunks (im Falle von Ogre als ManualObject), in meinem Falle habe ich meist 600 Chunks pro Planet verwendet um pro Element die Anzahl Vertices/Triangles zu verändern.
Zu meinem Vorgehen an dieser Stelle, ein Planet besteht also aus einer Liste von "ManualObjectContainern", wo neben dem ManualObject auch in einem Array die Vertices und TriangleIndices vorgehalten werden, auf welchen ich ständig arbeite. Allerdings kam ich an dem Punkt noch nicht weiter wo ich die Vertices ausreichend Dicht generieren konnte um die gewünschte Detailgenauigkeit zu erzeugen. Bei 600 ManualObjects kam ich auf eine maximale Dichte von 250x250 Vertices. Bei Erhöhung der Anzahl Vertices oder Anzahl ManualObjects war dann schnell schluss.
Bilder (aus der Axiom3D/C# Variante)
Das LOD/Horizon Culling eines Planeten:
Video (mit Blick auf die Triangles):
http://youtu.be/BttXQpXNNGc
Durch die Schwierigkeiten kan diesem Punkt kam der Entschluss die Engine auf Ogre3D und C++ zu portieren, da die Community um das native Ogre3D (Axiom3D ist ja ein C# Wrapper von Ogre) und generell zu C++ größer ist.
Auch gab es bei bestimmten Features (Point Sprites, um sehr weit entfernte Objekte als Point Sprite anstatt Mesh darzustellen) nicht den vollen Support beim Wrapper.
D.h. im Moment arbeite ich daran die Portierung vorzunehmen. Mit einem Punkt, der Erzeugung von Nebeln, habe ich mich während der Portierung noch beschäftigt. Ich werde voraussichtlich darauf setzen Point Sprites zu verwenden, additives blending, und die Generierung mittels Strange Attractor vorzunehmen. D.h. ich hätte eine prozedurale Generierung, der User könnte diese Nebel bereisen und sie würden quasi-volumetrisch wirken, und die Nebel blenden bei ausreichender Nähe langsam aus (im Universum haben Nebel ja eine nur sehr geringe Dichte, und der reisende würde diese nur ab einer gewissen Distanz wahrnehmen.
Ich habe dies sehr dirty und schnell getest, und werde wohl in dieser Richtung weiter machen. Allerdings muss ich mich noch mit den Algorithmen hinter Strange Attractor auseinandersetzen (ggf. in Kombination mit Perlin Noise), um glaubhaftere strukturen zu generieren, die weniger Matematisch aussehen.
Video (sorry für die schlechte Qualität, es muss schnell gehen daher hat spontan das iPhone hergehalten :) ):
http://youtu.be/v6yHGjd5zHE
Status (auf Basis Ogre3D/C++):
Portierung zu Ogre/C++ (1%)
* Generierung Prozedural eines Galaxy (80% / bleibt auf C#)
- Prozedurale Namensgenerierung (100%)
- Umstellung auf Verteilung der Obekte zu Spiralstrukturen (0%)
- Erhöhung der Anzahl auf ca. 100.000 (0%)
* Einlesen XML-Konfiguration einer Galaxie (0%)
* Umstellung der Universum-"Strategie" sodaß es nicht aus einer Galaxy besteht sondern mehreren (um den Reisebereich zu vergrößern) (0%)
* Separater Updatethreads
- für LOD Aktualisierung Universum-Objekte (0%)
- für Planetenoberfläche (0%)
* Erzeugung Planet (0%)
- mit verbesserter Strategie für Oberfläche (Horizon-Culling, ggf. Frustum Culling, verbessertes Chunking. http://acko.net/blog/making-worlds-1-of ... and-cubes/ )
- Erneutes Chunking einzelnes Chunks anstatt nur Split/Merge von Triangles (bzw. Erhöhung/Verringerung von Vertices pro Chunk)
- dynamische Texturierung
* Erzeugung Sonne (10%)
* Erzeugung Gasplanet (0%)
* Erzeugung Schwarzes Loch (0%)
* Erzeugung Nebel (1%)
- Tuning Algorithmen
- Speicherung/laden von Position und Seeds der Nebel in einer separaten XML Konfiguration
Die Portierung wird mich jetzt erstmal ein Weilchen beschäftigen... ;-)