[Monogame/XNA] 3D-Voxel-Planet-Renderer

    • C#
    • .NET (FX) 4.5–4.8

    Es gibt 14 Antworten in diesem Thema. Der letzte Beitrag () ist von φConst.

      [Monogame/XNA] 3D-Voxel-Planet-Renderer

      Was ist "Level of Detail (lod)"?

      Beim sogenannten "Level of Detail" wird anhand der Position des Spielers ermittelt, welchen Detailsgrad (level) einer Umgebung präsentiert werden soll.
      Dadurch kann die Effizienz des Spiels drastisch gesteigert werden.

      Um zudem dem Spieler eine große Welt zu suggerieren, wird nebstdem die Geschwindigkeit des Spielers relativ zur der Distanz zur Umgebung angepasst.

      Dafür verwendet diese Demonstration die Formel




      Um das LOD zu erzielen, wird ein einfaches Quadtree verwendet; um den Spieler befinden sich sogenannte verschiedene "BoundingSpheres", die jeweils das Niveau des Detailreichtums repräsentieren.
      Jedes Mal, wenn eine BoundingSphere mit dem Quadtree kollidiert, wird das Feld rekursiv in vier weitere, halb so große, Felder zerteilt.
      Jedes dieser Felder repräsentiert dann einen Chunk in welchem dann relativ zur Größe entschieden wird, wie viele Vertices in jeweils diesem Chunk gespeichert werden sollen.

      SourceCode: Github.
      Und Gott alleine weiß alles am allerbesten und besser.

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „φConst“ ()

      Sphärische Quadtrees

      -1-
      Im kommenden Update wird' Level of Detail für Sphäroide unterstützt werden.
      Siehe dazu: mathproofs.blogspot.com/2005/07/mapping-cube-to-sphere.html

      Bilder:



      _
      Und Gott alleine weiß alles am allerbesten und besser.

      Radial-Blur Implementierung

      Man beachte folgenden Shader-Code: shadertoy.com/view/4sfGRn
      Dadurch ist es' möglich Sonnenstrahlen zu simulieren.
      Ergebnis:








      Vielleicht wird' eine Kombination mit dem hier stattfinden: [MonoGame]Minecraft-Klon
      Quasi ein Voxel-Weltraum-Spiel.
      _
      Und Gott alleine weiß alles am allerbesten und besser.

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „φConst“ ()

      Voxel-Planet mit LOD!

      Fortan wird der Planet voraussichtlich durch sogenannte "Voxels" repräsentiert: Dadurch ist es möglich den Planeten zu zerstören, bebauen et cetera!
      (Quasi als Erweiterung des Projekts [MonoGame]Minecraft-Klon).


      Anders als das vorherige Voxel-Projekt verwendet diese Variante den sogenannten "Marching-Cubes"-Algorithmus.
      (Wer mehr wissen will:
      youtube.com/watch?v=M3iI2l0ltbE
      paulbourke.net/geometry/polygonise/)

      Demonstrationsvideo:



      Mit Interpolation sieht es gar nach einer idealen Kugel aus:


      Modifikation des Planeten zur Laufzeit:


      Tunnel:


      _
      Und Gott alleine weiß alles am allerbesten und besser.

      Dieser Beitrag wurde bereits 4 mal editiert, zuletzt von „φConst“ ()

      Die bisherigen Bilder und Fortschirtte find ich echt erstaunlich, doch bei diesen beiden Bildern scheint irgendetwas mit der Beleuchtung/Farbgebung der Flächen nicht zu stimmen.
      Mein Hirn kann sich nicht entscheiden, ob das nun Berge oder Löcher sind, bzw. in welche Richtung die Flächen zeigen. Und je näher ich mir das ansehe, umso verrwirter bin ich :S

      EaranMaleasi schrieb:

      Die bisherigen Bilder und Fortschirtte find ich echt erstaunlich, doch bei diesen beiden Bildern scheint irgendetwas mit der Beleuchtung/Farbgebung der Flächen nicht zu stimmen.
      Mein Hirn kann sich nicht entscheiden, ob das nun Berge oder Löcher sind, bzw. in welche Richtung die Flächen zeigen. Und je näher ich mir das ansehe, umso verrwirter bin ich :S


      Ja, das stimmt noch vorne und hinten nicht ^^+.
      Und Gott alleine weiß alles am allerbesten und besser.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „φConst“ ()

      Interessanterweise können die UV-Koordinaten direkt aus den interpolierten Vertexposition relativ gut "abgelesen" werden:




      Sieht aus wie ein Golfball ^^+.

      Voxel-Ansätze bieten in der Tat große Vorteile.
      Die gesamte Kugel wird einfach durch die Formel:
      Radius * Radius - (x*x + y*y + z*z) repräsentiert: Dadurch ist es also möglich float-Datentypen als Koordinaten entgegenzunehmen.
      Die Positionsinformationen sind also in ein Gitter bestehend aus Skalaren eingebettet: Man braucht demnach nicht einmal ein Array!
      Es beansprucht konsequenterweise, selbst für große und komplexe Strukturen (z.B. generiert durch Simplex-Noise), kaum den RAM-Speicher.
      Einzige Voraussetzung: Man muss eine mathematische Formel konstruieren, die die Struktur repräsentiert, respektive, diese Struktur mathematisch beschreibt.

      Gesucht ist also eine Funktion die von IR^3 auf IR (Skalar) abbildet (also: f(x,y,z)).
      Will man aber die Struktur verändern (exemplarisch Teile von ihr zerstören, oder bebauen), so sind zusätzliche Daten notwendig: Man hinterlegt z.B. in eine Liste
      BoundingSpheres und prüft in der Funktion f: IR^3 -> IR, ob das Tupel (x,y,z) in BoundingSphere enthalten ist. Wenn ja: Bestimmten Skalar liefern, wenn nein, Berechnung fortsetzen.


      _
      Und Gott alleine weiß alles am allerbesten und besser.

      Dieser Beitrag wurde bereits 8 mal editiert, zuletzt von „φConst“ ()

      Textur wird nun ohne Texture-Koordinaten auf das Terrain gemappt:


      Wenn jemand wissen will wie das geht:

      Notwendig hierfür sind die Position und die Normale eines jeden Vertex'.
      Im Pixel-Shader werden dann alle möglichen 2D-Koordinaten-Komponenten-Kombinationen (welche jeweils skaliert werden) in
      jeweils drei (3 Komponenten (x,y,z) auf 2 Plätze verteilen : 3C2 = 3) float2-Variablen gespeichert und jeweils dreimal die Textur mit den entsprechenden Komponenten-Kombinationen
      gesamplet.

      Danach wird der Normalen-Vektor benutzt um die entsprechenden float4() Werte die aus dem tex2D() resultieren, zu gewichten.

      Lautet exemplarisch die Gleichung f: IR^3 -> IR, f(x, y, z) = 50 - y;
      (also die x-z-Ebene), so ist der Normalenvektor dieser Ebene (0, 1, 0).

      Entsprechend lautet dann die Gewichtung:
      position.xy * normal.z + position.xz * normal.y + position.zy * normal.x = position.xz.
      Und das ist dann auch schon die korrekte "Textur-Koordinate" für die Vertizes.

      Wer mehr wissen will: catlikecoding.com/unity/tutori…dering/triplanar-mapping/

      Code:

      C#-Quellcode

      1. float4 triplanarTexture(sampler textureSampler, float3 pseudoUV, float3 normalizedVector)
      2. {
      3. float2 texel1 = pseudoUV.xy * ScaleA;
      4. float2 texel2 = pseudoUV.xz * ScaleB;
      5. float2 texel3 = pseudoUV.yz * ScaleC;
      6. float4 data0 = tex2D(textureSampler, texel1);
      7. float4 data1 = tex2D(textureSampler, texel2);
      8. float4 data2 = tex2D(textureSampler, texel3);
      9. float3 normal = normalizedVector / (normalizedVector.x + normalizedVector.y + normalizedVector.z);
      10. return (data0 * normal.z + data1 * normal.y + data2 * normal.x);
      11. }


      _
      Und Gott alleine weiß alles am allerbesten und besser.

      Dieser Beitrag wurde bereits 2 mal editiert, zuletzt von „φConst“ ()

      Bluespide schrieb:

      Du solltest dir aber noch unbedingt "Mip Mapping" anschauen






      Gott sei Dank stellt Monogame so eine Option schon bereit.
      Und Gott alleine weiß alles am allerbesten und besser.

      Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „φConst“ ()