fvoxel

reinhard@finalmedia.de cafeface
Tue Jul 14 10:54:44 AM CEST 2026
Public Domain

  • readme.txt
  • fvoxel.tgz code, doku, examples
  • fvoxel.c
  • fvoxel binary (amd64) 4a25011d6989b04ead2508da260af147b2f0fcacd85bdb218feac8ef379604b1
  • rundflug.txt
  • maps/map.txt.gz (7.6 MB)
  • fvoxel Engine Befehle

    fvoxel liest auf stdin fvoxel befehle und gibt auf stdout fdraw befehle aus.

    Eigentlich weniger Voxel, sondern ein Heightmap-Raycasting Verfahren, wie es in den 90er Jahren von NovaLogic unter Kyle Freeman für das Computerspiel "Comanche: Maximum Overkill" genutzt wurde. NovaLogic hatte es als "Voxel Space Engine" bezeichnet, und das Verfahren 2001 in den USA unter US6700573B2 als Patent angemeldet. 2021 ist das Patent aber ausgelaufen und seit 2016 existiert auch die NovaLogic Inc. nicht mehr. Der Voxel-Space-Algorithmus ist heute technisches Allgemeingut.

    Voxel klingt auch schöner, als Heightmap-Raycasting, daher auch hier der Name fvoxel.

    Wir nutzen eine 2D-Heightmap (Höhenkarte) und eine 2D-Colormap (Farbkarte). Die Engine wirft Strahlen von der Kamera aus nach vorne (Raycasting). Für jeden Spaltenpixel auf dem Bildschirm wird in der Heightmap nachgesehen, wie hoch das Gelände an diesem Punkt ist, und eine vertikale Linie (ein Höhenstab) in der Farbe der Colormap gezeichnet.

    Da pro X/Y-Koordinate immer nur ein einziger Höhenwert existieren kann, handelt es sich technisch gesehen um ein 2,5D-Verfahren (Höhenfelddarstellung). Überlappende Strukturen wie Brücken, Tunnel oder echte Höhlen sind mit dem Verfahren unmöglich. Das Verfahren ist jedoch extrem schnell und erlaubte auch für damalige DOS-Rechner eine revolutionär detailreiche und flüssige Landschaftsdarstellung, die ihresgleichen suchte.

    In fvoxel kombinieren wir die Colormap und Heightmap. Zudem bieten wir Colorcycling an, um die Darstellung noch realisistischer zu machen, z.B. für Wassereffekte etc. Die Kamera ist frei positionierbar./p>

    Im Gegensatz zu fdraw verwendet fvoxel statt Kleinbuchstaben einzelne Großbuchstaben als Befehle.

     M x y h r g b .......... Mapdatazeile x y heightmap_value(gray) color r, color g, color b setzen
     P x y h r p z .......... Position der Kamera auf der Map (x,y), Hoehe, Drehung, Pitch und Zoom setzen
     C r g b t n rn gn bn ... Colorcycling Slot definieren Originalfarbe (r,g,b), timedelay in ms, slotnumber, slot r,g,b
    

    Mittels M können also Punkt für Punkt Map Daten gesetzt und verändert werden.

    Mittels P kann die Position der Kamera gesetzt und verändert werden.

    Für alle Werte gilt... Buchstaben A-Z als Befehle. Jeweils positive Ganzzahlen. Für Drehung ist es 0 bis 360 (als Gradangabe), Für Pitch ist es 0 bis 360 (als Gradangabe) Für Zoom ist es 0 bis 1000 (als Prozentuale angabe). Teleobjektiv höherer Wert, 100 ist Fischauge. 150 normal.

    Damit kann man nun eine Terrain Map via stdin laden und eine Kamera positionieren. Sobald eine Kameraposition gesetzt wird, wird der Frame und die Voxelwelt neu berechnet.

    Dabei kann der Raum auch verändert werden, also man kann Berge, Täler und Flüsse entstehen lassen oder auch die Vegetation und Schatten (Farbe) verändern, indem man einzelne M Befehle neu übergibt und die Kamera wieder setzt.

    Map

    Der Tarball beinhaltet das nachfolgende Beispielmap. Sie ist als zufallsgenerierte, partiell seamless tilemap in 1024x1024 zu sehen. Tile wrap. als Beispiel und start.sh erstellt daraus mit imagemagick dann die map.txt. Alles weitere bitte in der start.sh nachlesen. Dort sind konkrete Beispiele für Animationen genannt.

    Das System kann auch mit 4096x4096 Maps arbeiten.

    Colormap

    Heightmap

    Beispielkarten

    Fertig gerechnete Beispielkarten 1024x1024 im fvoxel Befehl Format, also als M Lines:

    Zum Erzeugen obiger Karten habe ich nachfolgende Pipeline verwendet

    Zunächst wurde in cotamap ein realworld ausschnitt gewählt und eine 8bit png heightmap und eine darauf basierende procedural terrain textur (colormap) als png erzeugt und gespeichert.

    Diese heightmap und colormap wurde dann mittels imagemagick in txt format und mittels awk in fvoxel befehle als txt gewandelt. die rundflug.txt enthält wiederum die Kamerapositionierungsbefehle und kann letztlich dann auf alle maps angewendet werden. Hier sind natürlich beliebige Kamerabewegungen, Winkel und Positionen auf der Map möglich. rundflug.txt gibt somit immer nur ein rasches preview nach laden der Karte.

     # Height und Colormap als txt format extrahieren
     convert heightmap1024.png -filter Gaussian -blur 0x8 -compress none txt:- | awk -F'[(,):]' 'NR>1 {print $1, $2, int($4)}' > heightmap.txt
     convert colormap1024.png -compress none txt:- | awk -F'[(,):]' 'NR>1 {print $1, $2, int($4), int($5), int($6)}' > colormap.txt
     
     # map.txt merge heightmap und colormap. Jede Zeile als "M" Zeile generieren
     paste heightmap.txt colormap.txt | awk '{print "M", $1, $2, $3, $6, $7, $8}' > map.txt
     
     export SCREEN_WIDTH=640 SCREEN_HEIGHT=480
     cat map.txt rundflug.txt | fvoxel | fdraw | ffplay -loglevel 8 -f rawvideo -pixel_format rgba -video_size 640x480 -framerate 30 -i -
    

    Wie erwähnt, arbeitet das System auch mit 4096er Maps und auch noch größer. Eine 4096x4096 map als textbasierte M Befehle wird aber bereits 360 MB groß, wohingegen 1024x1024 um die 23 MB belegen

    Beispielnutzung von mapdaten als stream:

    export SCREEN_WIDTH=120 SCREEN_HEIGHT=80
    (curl -Ls https://finalmedia.de/code/fvoxel/maps/map.1024.alpen.txt.gz  | zcat; awk 'BEGIN{while(1){for(i=0;i<=360;i++)print"P 512 512 480",i,"90 90"}}') | fvoxel | fdrawterm
    

    Generatoren

    Es gibt einige freie Heightmap und Colormap Generatoren, offline wie online. Hier einige Online Generatoren: