Maps bauen
-
Hallo zusammen,
ich möchte für ein Spiel ein map-format entwerfen, habe damit allerdings noch keine praktischen erfahrungen; nur "trocken" überlegungen gemacht. mein fachklassenentwurf sieht erstmal so aus:
class Map { // terrain -> berge, ebenen etc; s.u. private TerrainData terrainData; // sachen zum einsammeln private List<Item> items; // objekte wie bäume, häuser -> modelmeshes private List<MapObject> objects; } class TerrainData { // Heightmap als 16 Bit Graustufen-Bild private Texture heightMap; // Textur zum "drüberlegen" über die heightmap private Texture texture; } class MapObject { // position -> 3D-Vektor private Vector3 position; // modelmesh private Model model; }
ich bin allerdings etwas unsicher, ob meine herangehensweise die richtige ist - ich hab noch nie mit heightmaps gearbeitet, deshalb eine grundsätzliche frage dazu:
so wie ich es verstehe, wird die heightmap in ein mesh umgewandelt. geschieht dies zur laufzeit, wenn meine map geladen wird? oder sollte man das schon vorher kompilieren und das fertige mesh laden?
wird die geländetextur dann einfach über das geländemesh "drübergelegt", oder sollte man hier lieber stück für stück mit höhenabhängiger textur rendern?
ist meine herangehensweise so sinvoll? ich hab angst, dass ich etwas wichtiges vergessen habe, was man dann erst zu spät merkt und dann ist die ganze arbeit für die katz.
zum speichern der map: ich habe vor, so etwas wie einen map compiler zu bauen, der dann die map aus z.b. xml in ein binärformat übersetzen kann. sollte ich also hier dann schon die heightmap in ein mesh umwandeln?
was die objekte betrifft, denke ich dass es kein problem sein sollte, diese einfach auf das terrain "draufzustellen".
es wäre toll, wenn mir jemand helfen kann herauszufinden, ob ich in die richtige richtung denke, bevor ich ins kalte wasser springen muss. gruß und vielen dank
-
wird die geländetextur dann einfach über das geländemesh "drübergelegt", oder sollte man hier lieber stück für stück mit höhenabhängiger textur rendern?
Du solltest Dir ueberlegen wie gross der durchschnittlich sichtbare Ausschnitt im Verhaeltnis zur Gesamtgroesse des Terrains ist.
Sieht man jeweils nur einen kleinen Teil des Terrains wirst Du mit einer einzigen Textur nicht weit kommen (ein Texel ist im Viewport dann riesig).
Die Texturierung eines Terrains ist abhaengig von vielen Faktoren.
Einige ergeben sich aus der Geometrie selbst (Hoehe, Steigung, etc), andere werden manuell festgelegt (Gestein, Erde, Bewuchs), wieder andere ergeben sich aus deren Kombination. Ist zb eine steile Wand haeufig Regen ausgesetzt wird dort die Erde groesstenteils weggespuelt sein, darunter hat sich entsprechend mehr angesammelt.
Wieviel Arbeit dabei der Artist und wieviel der Coder uebernehmen soll musst Du selbst entscheiden (beide liefern gute Ergebnisse, siehe Terragen etc).
Da das Terrain ggf viel Einfluss auf das Gameplay/Leveldesign nimmt wuerde ich erstere Herangehensweise bevorzugen.
Generell arbeitet man haeufig mit vielen kleinen Tiles fuer die man pro Vertex oder in Form einer zusaetzlichen Textur spezifiziert, wie stark diese sichtbar sind - so bekommt man einen weichen Uebergang von einem Untergrund zum anderen.ich habe vor, so etwas wie einen map compiler zu bauen, der dann die map aus z.b. xml in ein binärformat übersetzen kann. sollte ich also hier dann schon die heightmap in ein mesh umwandeln?
Du musst ja sowieso fuer jeden Teil Deines Terrains einen Vertexbuffer erzeugen. Ob Du die Koordinaten dafuer nun aus der einen oder aus der anderen Datei nimmst ist egal.
ist meine herangehensweise so sinvoll? ich hab angst, dass ich etwas wichtiges vergessen habe, was man dann erst zu spät merkt und dann ist die ganze arbeit für die katz.
Das passiert beim ersten Mal sowieso
-
Ich beschäftige mich nun auch schon etwas länger mit Terrain rendering. Das wohl kleinste format für ein Terrain ist das Raw Format. Das Raw Format ermöglichst dir maximal 256 Höhenstufen und jeweils 1 Byte steht für ein Vertex. Ist deine Map also 200x200 groß, hat die Datei 200x200 Byte = 40000 Byte. Vorteil ist auch das man die Map so auch sehr einfach und sehr schnell laden kann.
Zum Texturieren giebt es eine vielzahl von Techniken, mein persöhnlicher favoriet ist das Textur-Splatting. Textur splatting funktioniert im prinziep ganz einfach. Du hast ein kleie kleinere Textur, die über das ganze Terrain gelegt wird, und für jede der 4 Farben, steht eine Textur. Ist zum beispiel an dieser Position mehr rot, wird zum beispiel die Gras Textur an dieser Stelle intensiver. Vorteil daran ist, das man sehr große freiheiten hat und schön weiche übergänge. Leider erfordert diese Technik kenntnisse in HLSL bzw GLSL.
Wie das terrain aufgeteilt wird, hängt davon ab, von welcher perspective man auf das Terrain schaut und wie groß es ist. Wenn man aus der First-Person perspective auf das Terrain schaut, sollte man sich mit LOD Algorythmen auseinander setzen. Wenn man jedoch wie in einem Strategiespiel von oben auf das Terrain hinab schaut, benötigt man kein LOD Algorythmus. In diesem Fall reicht es aus das Terrain in einzelne Patches (Teile) auf zu teilen, und nur die Teile der Map zu zeichnen, welche auch wirklich sichtbar sind.
Die Vorteile an Textur-Splatting sind, das man sehr einfach einen Map Editor realisieren kann, da man nur die Color-Map bearbeiten muss.
Welches Format du für die Map benutzt, hängt ganz von dir ab, empfehlen würde ich dir für das Terrain das Raw fromat. Für Modelle etc hängt es ganz von dir ab. An deinem Code Beispiel konnte ich erkennen, das dein Map fromat auch Modelle und Items, beispielsweise für ein Spiel beinhalten soll. Ich würde alles in seperaten dateien schreiben. Eine Datei für die items, in der dieeigenschaften der items stehen und auf das Modell des Items verwiesen wird. Die Modelle würde ich jeweils einzelnd specihern und die Map dann halt auch. Anschließend würde ich alle dateien in einer Container Datei zusammen packen, vorteil: Man kann eine verschlüsselung und Passwortschutz einbauen ...
-
vielen dank für eure antworten. das sind schonmal sehr hilfreiche anregungen und ich merke direkt, dass ich (mal wieder) nicht an alles gedacht habe. ich hatte leider noch keine gelegenheit mich dranzusetzen; am wochenende vielleicht.
nochwas: wan erzeuge ich nun das mesh aus der heightmap? zur laufzeit? (ist das nicht langsam?) oder schon zur entwicklungszeit, sodass nur noch binäre mapdaten im spiel geladen werden müssen? aber wenn ichs zur laufzeit mache beschränke ich mich damit bestimmt, nicht wahr?
die sache ist die - ich hab mir vorgenommen, das terrain deformierbar zu machen, allerdings fürchte ich, dass ich mir damit wohl ziemlich viel vorgenommen habe. ich glaube, ich sollte erstmal versuchen, das normale terrain hinzubekommen
-
1.) Wenn du das Terrain aus Raw Dateien lädst, hast du es doch schon im Format, welches man am schnellsten laden kann. Das Terrain würde ich, einmal laden. Wenn man zum beispiel das "Spiel" beginnt, kannst du das Terrain laden.
2.) Das Terrain ist Devormierbar, eigentlich ist jedes Terrain devormierbar. Die Technik die ich benutze macht das devormieren soger relativ einfach. Schließlich ist der Editor ja auch zum "devormieren" gedacht.
Ich empfehle dir ersteinmal ein ganz einfaches Terrain zu machen. Du hast ein bild, von der größe 64x64 pixel. Das Bild lädst du, und generierst daraus die höhendaten. Du erstellst den Vertexbuffer, und füllst in mit den daten, schön der rheie nach. Anschließend benutzt du einen Index Buffer um aus den Verticen ein paar poligone zu machen. Anschließend zeichnest du einfach den Vertex Buffer. Anschließend kannst du dann mit dem nächsten schritt weiter machen, versuch das Terrain zu devormieren. Am einfachste währe es, für jeden Vertex, den vertexbuffer an der stelle zu locken, den vertex zu verändern und dann wier unlocken ...
Für ein einfaches Terrain kann ich dir das Tutorial empfehlen:
http://www.riemers.net/eng/Tutorials/DirectX/C++/Series1/tut11.php
Ganz unten ist der gesammte code des tutorials!