#!/usr/bin/gawk -f # reinhard@finalmedia.de # Thu May 14 11:07:10 AM CEST 2026 # Public Domain # Beispiel: gawk -v width=640 -v height=480 -f starfield.awk > /dev/shm/videocmd BEGIN { if (!width) width = 1920; if (!height) height = 1080; # Anzahl der Sterne im 3D-Raum num_stars = 20000; # Bildschirmmittelpunkt (Fluchtpunkt für 3D) cx = width / 2; cy = height / 2; srand(); # 1. Sterne im virtuellen 3D-Raum initialisieren # X und Y gehen von -1000 bis +1000, Z (Tiefe) von 1 bis 1000 for (i = 0; i < num_stars; i++) { star_x[i] = int(rand() * 2000) - 1000; star_y[i] = int(rand() * 2000) - 1000; star_z[i] = int(rand() * 1000) + 1; } # Geschwindigkeit der Bewegung durch den Raum speed = 15; # Hauptschleife für die Animation while (1) { # Bildschirm leeren für den neuen Frame print "c 0 0 0"; print "m 0 0"; print "r " width " " height; # Alle Sterne aktualisieren und zeichnen for (i = 0; i < num_stars; i++) { # Stern bewegt sich im 3D-Raum auf uns zu (Z wird kleiner) star_z[i] -= speed; # Wenn der Stern uns passiert hat, wird er im Hintergrund neu geboren if (star_z[i] <= 0) { star_x[i] = int(rand() * 2000) - 1000; star_y[i] = int(rand() * 2000) - 1000; star_z[i] = 1000; } # 3D-Projektion auf den 2D-Bildschirm: (Achsen / Tiefe) + Bildmitte # Faktor 500 steuert das Sichtfeld (Field of View) sx = int((star_x[i] * 500) / star_z[i] + cx); sy = int((star_y[i] * 500) / star_z[i] + cy); # Prüfen, ob der projizierte Stern sichtbar ist if (sx >= 0 && sx < width && sy >= 0 && sy < height) { # Helligkeits-Fading: Je näher der Stern (kleines Z), desto heller # Sterne im Hintergrund (Z=1000) sind fast schwarz, vorne (Z=0) reinweiß brightness = int((1000 - star_z[i]) / 1000 * 255); if (brightness < 30) brightness = 30; # Mindesthelligkeit if (brightness > 255) brightness = 255; # Stern als Pixel zeichnen (Weiß/Graustufen) print "p " sx " " sy " " brightness " " brightness " " brightness; } } # Frame-Timing senden (ca. 60 FPS -> 16,6ms) print "s 16666"; fflush(); } }