reinhard@finalmedia.de cafeface
Wed Jul 29 11:57:04 PM CEST 2026
Public Domain
fretina liest steuerungsbefehle (kameraposition und worldloader) von stdin und gibt rgba frames auf stdout aus.
fretina ist ein filesystembasierter highspeed Software 3D-Renderer fĂŒr Hyper Gaussian Splats in (Fixpoint Arithmetik) inkl. Spherical Harmonics.. (BlickwinkelabhĂ€ngig Ănderungen bei der Farbgebung von Pixeln fĂŒr hohen Realismus bei Spiegelungen, Transparenzen, irisierenden Farben).
Ziel der Implementierung ist ein leicht portierbarer, minimalistischer, hoch optimierter, speichereffizienter und echtzeitfÀhiger 3D-Grafik-Renderer ohne externe AbhÀngigkeiten.
fretina wurde fĂŒr eingebettete Systeme oder minimalistische Umgebungen im puristischen djb-Programmierstil entwickelt.
Das Tool liest kontinuierlich Kamerabefehle ĂŒber die Standardingabe (stdin) ein und streamed eine in sich selbst animierte Gaussian Splat Welt aus einer lokalen wohldefinierten Verzeichnisstruktur aus Ordnern, Dateien und Symlinks. Es rendert diese abhĂ€ngig von der ĂŒbergebenen Kameraposition (x y z pan tilt brennweite) und gibt die fertig gerenderten Videobilder (als RGBA-Frames) ĂŒber die Standardausgabe (stdout) aus.
Die Gesamte Welt ist dabei durchwanderbar und Daten werden dabei erst on demand geladen. So muss nie die gesamte Welt in den Arbeitsspeicher geladen werden. Pro Block sind dabei >24h Gaussian Splat Animation möglich, die jeweils beginnt, wenn der Block betreten wird. Da die Weltblöcke als viele tausende kleine Dateien fester GröĂer (4MB) existieren sind sie parallel von anderen Tools zur Laufzeit verĂ€nderbar. Die Weltblöcke (Sektoren) beinhalten dabei jeweils maximal 262.144 Splats. Die DateigröĂe wurde fĂŒr ein optimales Streaming von ext4 Dateisystemen gewĂ€hlt. Durch Symlinks sind 0-Byte Belegungen möglich, wenn sich einzelne Blöcke nicht Ă€ndern.
Neben den bereitgestellten Proof-Of-Concept Weltgeneratoren empfiehlt sich zur raschen Sichtung im Terminal die Verwendung von
rgba2fdraw s 33333 | fdrawtermaus dem fdraw Paket, um z.B. auch die Ausgabe via ssh auf einem Terminal auszugeben. Alternativ kann das bekannte ffmpeg verwendet werden, um die rgba Ausgabe live darzustellen oder in Videos zu rendern.
P x y z pan tilt zoom brennweite Kamera positionieren W d wechselt in das angegebene Welten Verzeichnis d, bestehend aus 4 Dezimalstellen
Beispiel fĂŒr einen Wechsel in das Welten-Verzeichnis W0001 ist der Befehl "W 0001" und das Programm verwendet dann adhoc die Struktur W0001/0000/0000/0000/000000.p - W0001/9999/9999/9999/99999.p
make make myhelix make activate make fly
Um nicht die gesamte 3D-Welt im Arbeitsspeicher halten zu mĂŒssen, nutzt das Programm ein cleveres, dateibasiertes Streaming-Verfahren:
Der Code verzichtet komplett auf FlieĂkommazahlen (float/double), was ihn auf Systemen ohne mathematischen Koprozessor oder im Kernel-Space extrem schnell macht:
Sobald ein Befehl vollstÀndig ist (entweder durch ein Newline \n oder nach dem 7. Parameter), erhöht das Programm den globalen ZeitzÀhler (gt++).
Bevor gezeichnet wird, setzt das Programm alle Bildpuffer zurĂŒck: Die Farb- und Alpha-KanĂ€le werden auf 0 gesetzt, der Tiefenpuffer (ret_z) auf den maximalen Integer-Wert 32767.
Danach lĂ€uft eine Schleife ĂŒber alle 262.144 möglichen Splats (TOT_SPL):
Ganzzahl-3D-Animation (Wellen-Effekt): Hat ein Splat eine hohe Lebensdauer (dt >= 100), wird er pro Frame animiert. Das Programm berechnet mittels get_atan2 den Polarwinkel der XZ-Ebene und moduliert den Radius ĂŒber eine Multiplikation von Sinus- und Kosinuswellen (s_wave * c_wave). Dies erzeugt ohne jegliche FlieĂkommazahlen rotierende oder pulsierende Wellenbewegungen der Punkte im Raum.
Ein Gaussian Splat ist kein eckiges Pixel, sondern ein weicher, meist elliptischer Punkt. Das Programm berechnet die Radien (emaj fĂŒr die Hauptachse, emin fĂŒr die Nebenachse) sowie eine Scherung (sch) basierend auf der Entfernung rz.
Befindet sich der Pixel innerhalb der GauĂ-Kurve, greifen die finalen Grafik-Regeln:
Nachdem alle 262.144 Splats verarbeitet wurden, kopiert eine ultraschnelle Schleife die separaten FarbkanÀle (ret_r, ret_g, ret_b, ret_o) sequentiell in den finalen, linearen Ausgabe-Puffer fb.
Mittels eines ununterbrochenen Systemaufrufs write(1, fb, fb_sz) wird dieser Rohdaten-Frame (RGBA) direkt auf die Standardausgabe (stdout) geschoben, bereit fĂŒr die Weiterverarbeitung.
Die maximale GröĂe der darstellbaren Welt wird durch zwei Faktoren limitiert: das Sektor-Koordinatensystem in der Funktion gen_path und die Auflösung der Festkomma-Mathematik. Die theoretischen und praktischen Grenzen der WeltgröĂe teilen sich wie folgt auf:
Der limitierende Faktor in gen_path() fĂŒr die GesamtgröĂe der Welt ist die Art und Weise, wie die Dateipfade fĂŒr die Sektoren generiert werden. In der Funktion gen_path limitiert der Code die Sektorkoordinaten (ax, ay, az) hart auf einen Wertbereich von 0 bis 9999: Da ein Sektor eine SeitenlĂ€nge von 500 Einheiten besitzt (SEC_SZ = 500), ergibt sich daraus folgende Dimension:
Das ergibt einen maximalen 3D-Weltraum von 5000 Ă 5000 Ă 5000 Einheiten (bzw. 10.000Âł = 1 Billion Sektordateien auf der Festplatte).
Die Festkomma-Arithmetik im Code nutzt int32_t fĂŒr die Transformationen.
Wenn man eine Einheit als 1 Zentimeter definiert (was fĂŒr detaillierte Gaussian Splats ĂŒblich ist), kann dieses Programm eine nahtlos gestreamte 4D-Welt von exakt 50 Ă 50 Ă 50 Kilometern darstellen.
Wir belegen pro .p Datei exakt 4 MB Daten. Ein theoretischer Vollausbau dieses Dateisystems von 0000/0000/0000/00000 bis 9999/9999/9999/99999 wĂŒrde unvorstellbare 445,64 Zettabytes (ZB) bzw. rund 386.535 Exabytes (EB) an Speicherplatz belegen.
Diese astronomische Datenmenge setzt sich aus der Kombination von gigantischem 3D-Raum und der 5-stelligen Zeitschleife zusammen:
Multipliziert man alle Faktoren, landet man bei exakt 445.644.800.000.000.000.000.000 Bytes. Das entspricht:
~ 395.812.094 Petabytes (PB)
~ 386.535 Exabytes (EB)
Da das Programm ein "Sparse-Filesystem" nutzt (es öffnet Dateien nur bei Bedarf und ĂŒberspringt fehlende via fd >= 0), mĂŒssen auf der Festplatte nur die Sektoren tatsĂ€chlich existieren, in denen sich Geometrie befindet. Leere Bereiche im Universum belegen 0 Bytes.
Um die Auflösung bei realen Szenendaten (LiDAR-Scans oder 4D-Gaussian-Splat-Videos) zu bestimmen, mĂŒssen wir die rĂ€umliche Punktdichte (Auflösung im Raum) und die zeitliche Bildwiederholrate (Auflösung in der Zeit) betrachten.
Bei einem Vollausbau bietet dieses System eine Sub-Millimeter-PrĂ€zision im Raum und eine extrem flĂŒssige Kino-Zeitauflösung.
Jeder Sektor besitzt eine KantenlĂ€nge von 500 Einheiten und lĂ€dt eine .p-Datei mit exakt 262.144 Splats/Punkten (TOT_SPL). Wenn wir 1 Einheit als 1 Zentimeter definieren (womit die Gesamtwelt 50 Ă 50 Ă 50 km groĂ ist), ergibt sich fĂŒr einen einzelnen Sektor (5 Ă 5 Ă 5 Meter):
Skalierung auf Sub-Millimeter-Niveau: Gaussian Splats nutzen im Gegensatz zu harten LiDAR-Punkten weiche Ellipsen mit Transparenz. Setzt man 1 Einheit = 1 Millimeter (Gesamtwelt 5 Ă 5 Ă 5 km), schrumpft der Sektor auf ein handliches Volumen von 50 Ă 50 Ă 50 cm (0,125 mÂł).
Da jeder Splat eine Ausdehnung hat, entspricht dies einer fotorealistischen, lĂŒckenlosen OberflĂ€chenauflösung im Millimeterbereich, ideal fĂŒr die Archivierung von hochprĂ€zisen Drohnenscans oder volumetrischen Video-Aufnahmen von Menschen.
Die zeitliche Auflösung wird ĂŒber das Makro TPF 100 (Ticks Per Frame/File) und die 5-stellige Dateinummerierung definiert:
In der Praxis entsprechen 262.144 Splats pro 50 cm-WĂŒrfel der Detailstufe von modernen 4D-Gaussian-Splat-Verfahren (wie Deformable 3D Gaussians). Die Datenmenge pro Sekunde ist mit rund 2,5 MiB/s pro aktivem Sektor sogar extrem effizient kompiliert â sie liegt auf dem Niveau eines stark komprimierten 4K-Netflix-Videostreams, liefert dem Nutzer aber eine voll begehbare, volumetrische 3D-Umgebung.
Bei einer Kamerageschwindigkeit von 50 km/h betrĂ€gt die reine rĂ€umliche Streaming-Datenrate ca. 11,81 MiB/s. Wenn das Video gleichzeitig in Echtzeit (bei 60 Hz) weiterspielt, steigt die kombinierte Gesamtrate im Worst Case auf ca. 14,36 MiB/s. Die Berechnung basiert auf der logischen Annahme, dass 1 Einheit = 1 Zentimeter entspricht (SektorgröĂe = 5 Meter):
Selbst wenn die Kamera stillsteht, lÀdt das System im Zeitverlauf (4D-Video) Daten nach:
Die maximale Gesamtlast von ~14,36 MiB/s (ca. 115 Mbit/s) ist fĂŒr moderne Speichermedien extrem leicht zu bewĂ€ltigen. Selbst eine herkömmliche SATA-SSD (ca. 500 MB/s) oder eine langsame SD-Karte in einem Embedded System langweilt sich bei dieser Datenrate. Das Betriebssystem puffert die Daten dank des im Code genutzten POSIX_FADV_WILLNEED zudem perfekt im RAM vor.
Die maximale darstellbare Zeitdauer im System hĂ€ngt davon ab, mit welcher Frequenz (Bilder pro Sekunde) die Kamera-Steuerbefehle an den Renderer gesendet werden. Da der Code die Zeitepochen ĂŒber eine 5-stellige Zeichenkette im Pfad abbildet (von 00000 bis 99999), stehen exakt 100.000 diskrete Zeitschritte (Dateien) pro Sektor zur VerfĂŒgung. Hier sind die maximalen ZeitrĂ€ume fĂŒr die typischen Bildwiederholraten:
Wenn ein in der Pipe auf stdin exakt 60 Befehle pro Sekunde auflaufen:
Wenn das System als Langzeit-Archiv genutzt wird (z. B. ein Bild pro Sekunde fĂŒr LiDAR-VerĂ€nderungen im GelĂ€nde):
Im RAM wird der ZeitzÀhler als vorzeichenloser 16-Bit-Integer deklariert: uint16_t gt = 0;.
Ein uint16_t lĂ€uft bei 65.535 ĂŒber und springt zurĂŒck auf 0. Das bedeutet, nach exakt 655 Dateien (65.535 / 100) fĂ€ngt die Animation im Speicher wieder von vorne an (Loop-Effekt), obwohl auf der Festplatte Platz fĂŒr 100.000 Dateien wĂ€re.
Ja, exakt so funktioniert das System. Sobald du die rĂ€umliche Grenze eines Sektors ĂŒberschreitest, wechselt das Programm in ein komplett neues Verzeichnis auf der Festplatte (z. B. von W0001/5000/5000/5000/ nach W0001/5000/5000/5001/). In diesem neuen Sektor-Verzeichnis beginnt die Zeitrechnung fĂŒr die Dateien wieder komplett bei 00000.p, da der Pfad fĂŒr jeden Sektor individuell generiert wird. Hier sind die technischen Konsequenzen dieser Architektur:
Da jeder der 1 Billion Sektoren (10000^3) seine eigenen 100.000 Zeitdateien besitzt, ist die theoretische Gesamtlaufzeit der gesamten Welt gigantisch. Bewegt sich die Kamera kontinuierlich von Sektor zu Sektor vorwĂ€rts, könntest du das System ĂŒber Jahrhunderte laufen lassen, ohne jemals an das Ende der Zeitstempel zu stoĂen.
Zwei Szenarien, wie man das nutzen kann:
Exakt. Das ist der groĂe Vorteil des minimalistischen Datei-basierten Designs. Da der Renderer die 3D-Welt ausschlieĂlich ĂŒber das Dateisystem konsumiert und keine interne Datenbank fĂŒhrt, merkt er gar nicht, was unter der Haube auf Betriebssystemebene passiert.
Durch Standard-Linux-Mechanismen lÀsst sich das Basisverzeichnis W0000 nahtlos und unendlich im laufenden Betrieb austauschen, erweitern oder manipulieren. Da die Streaming-Datenrate bei 50 km/h mit rund 12 bis 14 MiB/s sehr moderat ist, lÀsst sich dieses System hervorragend mit Cloud-Speichern oder Netzwerk-Dateisystemen (wie rclone mount, NFS oder Ceph) koppeln.
Das Betriebssystem lĂ€dt ĂŒber den Mount-Point immer nur genau die 4-MB-Sektoren aus dem Internet oder dem Netzwerk nach, die die Kamera in diesem Moment anfordert. Dank posix_fadvise weiĂ der Linux-Kernel zudem vorab, welche Daten als NĂ€chstes blockweise geladen werden mĂŒssen.
Dazu muss man den Steuerbefehl W fĂŒr World nutzen, um zwischen Welten zu springen. "W 0023" wĂŒrde das basis verzeichnis w0023/ nutzen.
export SCREEN_WIDTH=320 export SCREEN_HEIGHT=240 fretina < epicfly.txt | gzip -9 > output.rgba.gz
export SCREEN_WIDTH=120 export SCREEN_HEIGHT=150 fretina < epicfly.txt | rgba2fdraw | fdrawterm
export SCREEN_WIDTH=120 export SCREEN_HEIGHT=150 cat kamera.txt | fretina | rgba2fdraw s 33333 | fdrawterm > demo.anim.gz zcat demo.anim.gz
export SCREEN_WIDTH=1920
export SCREEN_HEIGHT=1080
cat rundflug.txt | fretina | ffmpeg -y -f rawvideo -pix_fmt rgba -s ${SCREEN_WIDTH}x${SCREEN_HEIGHT} -r 60 -i - -c:v libx264 -an animation.mp4
export SCREEN_WIDTH=320
export SCREEN_HEIGHT=240
cat rundflug.txt | fretina | ffplay -f rawvideo -pixel_format rgba -video_size ${SCREEN_WIDTH}x${SCREEN_HEIGHT} -i -
mkdir config echo 150 > config/SCREEN_WIDTH echo 80 > config/SCREEN_HEIGHT cat rundflug.txt | envdir config fretina | envdir config rgba2fdraw | envdir config fdrawterm
yes P 0 0 0 0 0 100 0 | envdir termres ./fretina | envdir termres rgba2fdraw | envdir termres fdrawterm
gen_ programme erzeugen auf stdout einen tarball, den du entpacken kannst, um das world verzeichnis zu erstellen. prozeduraler democontent, teils animiert. man entpackt diese dann einfach einmalig
./gen_world | tar xvv 2>/dev/null ./gen_cyber | tar xvv 2>/dev/null ./gen_helix | tar xvv 2>/dev/null ln -s world W0000
Die Optimierung liegt in der mathematischen Harmonie zwischen den Hardware-Eigenschaften einer SSD (ext4-Dateisystem) und den Cache-Zeilen der CPU. Es gibt drei entscheidende GrĂŒnde, warum das Trennen in .p (Geometrie) und .m (Material) weitaus performanter ist, als die SH-Daten in eine einzige Datei mit weniger Splats zu quetschen:
Die Zahl 4 MiB (4.194.304 Byte) ist fĂŒr das Betriebssystem eine magische Grenze. Sie entspricht exakt den Speicherseiten (Huge Pages) des Kernels. Eine Datei mit genau 4 MiB wird von modernen NVMe-SSDs in einem einzigen, ununterbrochenen Hardware-Zyklus direkt in den RAM gestreamt. Wenn wir die SH-Daten in dieselbe Datei stecken, wĂŒrde sich die GröĂe eines einzelnen Splat-Blocks von 16 Byte auf ungerade 20 oder 24 Byte Ă€ndern. Das Problem: 4.194.304 Byte lĂ€sst sich nicht ohne Rest durch 20 oder 24 teilen. Wir hĂ€tten am Ende einer Datei ungenutzte FĂŒllbytes (Padding) oder Splats, die mitten ĂŒber eine harte 4-KiB-Dateisystemblockgrenze zerrissen werden. Das wĂŒrde bei jedem Lese-Vorgang zusĂ€tzliche SSD-Latenzen erzeugen.
Moderne Prozessoren laden Daten nicht byte-weise, sondern immer in Blöcken von 64 Byte (Cache Lines) in den ultraschnellen L1/L2-Cache. Getrennte Dateien: In unserem aktuellen Code rattert die CPU in der Pipeline-Schleife linear durch das p_pool-Array. Da ein Splat exakt 16 Byte groĂ ist, passen exakt 4 Splats in eine einzige 64-Byte-Cache-Line. Die CPU weiĂ im Voraus, was als NĂ€chstes kommt, und berechnet 4 Splats ohne einen einzigen Cache-Miss. Kombinierte Datei (z. B. 20 Byte): Ein Splat wĂŒrde ĂŒber die 64-Byte-Grenze des CPU-Caches hinausragen. Der Prozessor mĂŒsste mitten unter der Berechnung eines einzigen Splats anhalten und neue Daten aus dem langsameren Haupt-RAM anfordern. Das wĂŒrde die Framerate massiv einbrechen lassen.
Dadurch, dass die Materialdaten in der separaten .m-Datei liegen, nutzen wir das SĂ€ttigungsmodell optimal aus: Die CPU liest die Geometrie (.p) und transformiert die Punkte. Wenn die "Retina" an einer Koordinate bereits zu 255 gesĂ€ttigt (undurchsichtig) ist, bricht der Code sofort ab (return). Der Clou: FĂŒr all diese verdeckten Splats greift die CPU niemals auf das m_pool-Array zu. Wir sparen uns das rechenintensive Laden und Berechnen der SH-Blickwinkel aus dem Speicher fĂŒr alles, was ohnehin unsichtbar ist. WĂ€ren die SH-Daten mit der Geometrie verschmolzen, mĂŒssten wir sie gezwungenermaĂen immer mit in den Cache laden, selbst wenn der Punkt verdeckt ist.
Mit der Kombination aus einer 16-Byte-Geometrie (.p) und einem 1-Byte-Materialstrom (.m) bleibt alles perfekt auf Zweierpotenzen ausgerichtet. Das garantiert, dass weder auf dem SSD-Bus noch im CPU-Cache auch nur ein einziges Bit Speicherbandbreite verschwendet wird.
W0000/XXXX/YYYY/ZZZZ/TTTTT.SUFFIX
Verzeichnis-Layout: W0000/[S_x+5000]/[S_y+5000]/[S_z+5000]/[zeit_basis].p und .m
Jede Koordinate ist 4-stellig mit fĂŒhrenden Nullen (%04d).
Die zeit_basis ist 5-stellig mit fĂŒhrenden Nullen (%05d) und schreitet in 100er-Schritten voran (z.B. 00000, 00100).
.p-Dateien (HyperSplat4D Pool): MĂŒssen exakt 4.194.304 Bytes groĂ sein. Sie enthalten 262.144 Splats zu je 16 Bytes mit folgendem Packed-Layout:
int16_t x, y, z (Sektor-relative Koordinaten, 0 bis 499)
uint16_t t_start (0 bis 99)
uint8_t t_duration (Lebensdauer)
uint8_t opacity (Sichtbarkeit, >0 damit es gerendert wird)
uint8_t color_r, color_g, color_b, pad
.m-Dateien (Material/Glanz Pool): MĂŒssen exakt 262.144 Bytes groĂ sein. Sie enthalten 262.144 einzelne int8_t-Werte (Metadaten fĂŒr den Shading-Glanz), die eins-zu-eins den Splats zugeordnet sind.
Wir starten immer in W0000, wenn fretina aufgerufen wird.
Ein PâEintrag wird als TextâZeile auf stdin geschrieben. Die Zeile besteht aus dem Buchstaben P gefolgt von sieben ganzzahligen Feldern, die durch Leerzeichen getrennt sind und optional ein Vorzeichen - besitzen.
P\n
cam_x, cam_y, cam_z â absolute Kameraposition im WeltâKoordinatensystem.
Intern wird ein Offset von +250 zu cam_x und cam_y addiert, weil die DatenâChunks jeweils einen SektorâMittelpunkt bei (250,âŻ250,âŻ250) haben.
pan â horizontale SchwenkâKomponente (in BildâpixelnâĂ€hnlichen Einheiten).
WĂ€hrend der Projektionsrechnung wird pan * rz >> 9 zu xâKoordinate addiert, also ein BildâverschiebungsâEffekt, der stĂ€rker wirkt, je weiter das Objekt vom Beobachter entfernt ist.
tilt â vertikale SchwenkâKomponente (analog zu pan, wirkt auf die yâKoordinate).
zoom â additive Ănderung der effektiven Brennweite.
Die Formel fl = 300 + zoom bestimmt, wie stark das Bild âherangezoomtâ wird; ein gröĂerer Wert vergröĂert die projizierten Splats, ein kleinerer Wert verkleinert sie.
b_shift â âbrightnessâshiftâ (im Quellcode nur als b_shift gespeichert, aber nicht weiter verwendet).
Der Wert wird derzeit nicht in den RenderâBerechnungen ausgewertet, er ist also reserviert fĂŒr mögliche spĂ€tere Helligkeitsâ oder FarbâModulationen.
Das Programm liest die Zeile zeichenweise; erst nach dem abschlieĂenden ZeilenâBreak (\n) oder nach dem siebten ZahlenâToken wird die Zeile verarbeitet.
Was passiert bei Ănderung einzelner P Werte?
Parameter Erhöhter Wert â Was Ă€ndert sich im Bild
cam_x / cam_y Die Kamera verschiebt sich entlang der jeweiligen Achse. Das verschiebt das gesamte Bild horizontal/vertikal â Objekte erscheinen nach links/rechts bzw. oben/unten, weil die relative Lage zu cam_x / cam_y Ă€ndert.
cam_z Ăndert die Entfernung zum Beobachter. Ein gröĂerer cam_z (weiter weg) reduziert die projizierte GröĂe (fl / rz) und lĂ€sst die Szene âzusammenziehenâ. Ein kleinerer cam_z (nach vorne) vergröĂert die Objekte und verkĂŒrzt die TiefenÂperspektive.
pan Positive Werte drĂŒcken das Bild nach rechts (Objekte wandern nach links) â es wirkt wie ein Schwenk um die vertikale Achse. Negative Werte schwenken nach links. Der Effekt steigt linear mit der Tiefe rz (weiter entfernte Splats bewegen sich stĂ€rker).
tilt Analog zu pan, aber vertikal. Positive Werte kippen das Bild nach unten (Objekte bewegen sich nach oben), negative Werte nach oben. Auch hier gilt: Je gröĂer rz, desto stĂ€rker die Verschiebung.
zoom Erhöht die BasisâBrennweite (fl = 300 + zoom). Mehr Zoom â gröĂere projizierte SplatâGröĂen â Bild wirkt âgezoomtâ. Reduziertes Zoom (oder negative Werte) verkleinert das Bild, erweitert das Sichtfeld.
b_shift Momentan hat der Wert keine Auswirkung auf das Rendering; er bleibt im Code ungenutzt und kann spĂ€ter fĂŒr Helligkeitsâ oder FarbâOffsetâModulationen reserviert werden.
BeispielâSequenz
P 0 0 0 0 0 0 0 // Kamera im Ursprung, keine Schwenks, StandardâZoom
P 100 0 0 0 0 0 0 // Kamera 100âŻpx nach rechts â Szene wandert nach links
P 0 0 0 50 0 0 0 // PanâWert +50 â alle weiter entfernten Objekte verschieben sich nach rechts
P 0 0 0 0 0 100 0 // Zoom +100 â Bild âherangezoomtâ, Splats gröĂer