Das Raytracing Experiment

von Christoph

Die heißeste Schnittstelle für High-Performance Computergrafik neben DirectX 12 ist bekanntlich Vulkan und obendrauf einigermaßen aktuell ist Vulkan Raytracing. Ich schreibe einigermaßen, weil ich zugegeben etwas spät zu der Party bin. Zunächst sehr intensiv von Nvidia beworben, sind die mit ihrer Hardware inzwischen zu statistischen Sprachmodellen ("KI") weitergezogen. Nichtsdestotrotz fand ich Raytracing schon immer spannend. Das begann in den Neunzigern mit POV-Ray als die Generierung einer einzigen Grafik noch mehrere Sekunden bis Minuten brauchte. Jetzt soll es mit 60 FPS gehen? Muss ich sehen!

Zunächst einmal ist Vulkan keine einfache Schnittstelle. Ich würde sie grob dreimal so komplex wie OpenGL einschätzen und Raytracing dann nochmal doppelt so aufwändig. Der Umfang an Infrastruktur-Code ist enorm. Ich habe die ersten zwei Drittel des Experiments praktisch blind gearbeitet, was überhaupt nicht meinem iterativen Ansatz entspricht. Ich ändere Code und führe das Programm aus, um den Effekt zu sehen. Bei Vulkan-Infrastruktur gibt es da aber lange nichts zu sehen außer bestenfalls die Abwesenheit von Fehlermeldungen (das Validation Layer ist Gold wert, da hängt man Parameter- und Zustandsvalidierung vor den Grafiktreiber). Ebenfalls unpraktisch: für Vulkan Raytracing ist mir keine Software-Emulation bekannt. Ich musste komplett am Gaming-PC mit tauglicher Hardware entwickeln — Laptop auf der Couch oder am See ging nicht.

Screenshot SameGame RTX

Aber was soll ich sagen? Hardware-beschleunigtes Raytracing ist schon krass. Bei herkömmlicher Rasterisierung schickt man Objekt für Objekt (Untergrund, Haus, Baum) aus Dreiecken an die Grafikkarte und wenn es weit genug vorn liegt (Tiefentest), wird das Pixel entsprechend gefärbt. Beim Raytracing lädt man dagegen die gesamte Szene in den Grafikspeicher und schießt darauf so viele Strahlen wie man Pixel hat, also beispielsweise 800x600. Die Grafikkarte sagt dann einem Shader-Programm, das man vorher hochgeladen hat, welches Objekt getroffen wurde ("Glasfenster"). Hier wird es noch spannender. Man kann dann antworten: "Oh, Glasfenster. Kannst du mal verfolgen, welches Objekt der reflektierte Strahl trifft?" und die GPU kommt dann zurück mit "Baum". So kann man Spiegelungen nach einem physikalischen Modell statt mit mehreren Render-Durchläufen erzeugen.

Für SameGame RTX [676 kByte Zip-Download] habe ich mich da mal durch­gekämpft, allerdings mit nur einer Rekursionsstufe und sehr schwacher Reflexion. Wenn man ganz genau hinguckt, sieht man Spiegelungen benachbarter Kugeln. Es war wirklich heftiger Aufwand für so wenig Effekt, aber es ging ja ums Ausprobieren. Ich glaube, dass solche Projekte die Grenzen des persönlich Machbaren verschieben. Selbst wenn man nicht permanent auf der höchsten Schwierigkeitsstufe operiert, kann man auf niedrigeren davon profitieren, es mal getan zu haben. Ich bemerkte das beim Ray-picking. Da schießt man genau einen Strahl in die Szene (nämlich von der Maus-Position) und rechnet auf der CPU aus, welches Objekt getroffen (angeklickt) wird. Das benutzt man seit Jahrzehnten zum Beispiel in Echtzeit-Strategie­spielen, aber erst seit ich Raytracing durchgezogen habe, ist mir die Mathematik dahinter in Gänze klar. Eine sinnvolle Lektion für jede Art interaktiver 3D-Grafik.

Was mich zur abschließenden Bewertung bringt.

  • Für konservative Projekte mit durchschnittlichen Teams würde ich weiterhin OpenGL wählen. Das ist eine abgehangene, dokumentierte und überschaubare Technologie. Gutes Gelingen ist wahrscheinlich.
  • Wenn man etwas mehr Performance und Zukunftssicherheit für viel mehr Aufwand haben will und das Team zu den oberen 20% der Entwickler gehört, würde ich mich an Vulkan wagen. Das Projektrisiko ist signifikant, die Belohnung dann aber auch.
  • Um Raytracing würde ich einen Bogen machen, außer die Anforderungen leiten extrem deutlich in Richtung physikbasiertes Rendering. Selbst dann würde ich nochmal prüfen, wie es um die Unterstützung auf Grafikkarten steht. Ich wäre nicht überrascht, wenn Nvidia Raytracing für Gamer fallen lässt, weil Hardware für Rechenzentren profitabler ist. In jedem Fall würde ich ein Raytracing-Projekt nur mit den besten 5% der Entwickler anfassen.

Moralisch verwerflich?

von Christoph

Ich lese ja regelmäßig die Wirtschaftswoche (WiWo). Die Meinungsartikel triefen oft neoliberal und sind entsprechend schwer zu ertragen. Der Journalismus hat aber hin und wieder einen Lichblick - womöglich Brotkrumen, die beim paywall-vernagelten Handelsblatt runterfallen. Jedenfalls lese ich dort dieses Jahr das hier:

Die Organisation "Moral Rating Agency" führt eine Liste mit dem Namen "Dirty Dozen" – zwölf Konzerne, die sich angeblich aus Russland zurückgezogen haben, die aber in Wirklichkeit nach Informationen der "Moral Rating Agency" aber ein Großteil ihrer Geschäfte weiterlaufen lassen. Darunter bekannte Namen wie Unilever, Procter & Gamble, PepsiCo und Nestlé. Auch die Yale Universität führt eine "Liste der Schande".

Ui, ui, ui. Harte Worte: Moral, schmutzig, aber, aber, Schande. Naja, denke ich mir, Wirtschaftswoche eben. Aber Moment mal! Die vier Namen darin, die kommen mir doch irgendwie bekannt vor: Unilever, Procter & Gamble, PepsiCo und Nestlé. Woher nur? Aber ja! Das sind Konsumgüter Value-Aktien. Wenn man irgendetwas Robustes in seinem Depot haben wollte, das sich auch in Krisenzeiten stabil hält, dann würden die vermutlich in die engere Wahl kommen. Einen Sicherheitsanker habe ich ja selber. Also ganz genau gesagt, über die letzten 10 Jahre, vier Sicherheitsanker, nämlich: Unilever, Procter & Gamble, PepsiCo und Nestlé.

Tja. Zufälle gibts! Zu meiner Verteidigung kann ich sagen, dass sie dieses Jahr nicht über-performed haben. Ich habe also nicht übermäßig von Gierflation und Schande profitiert. Daher ja auch Sicherheitsanker (andere Erwartungshaltung).

Die wenigen Einzelwerte, die ich aus Spaß noch halte, wollte ich unter 4% je Position laufen lassen. Da hat mir Growth (Technologie-Werte, allen voran Nvidia) aber einen Strich durch die Rechnung gemacht. Der Growth- und der Value-Anteil waren tatsächlich mal gleich groß bei jeweils ca. 15%. Nach dem Auseinanderlaufen wäre eigentlich ein Rebalancing fällig gewesen, aber ich war zu faul. Habe es einfach laufen lassen und nicht zu Gunsten von Schande oder ETF umgeschichtet.

Damit bin ich dieses Jahr 2023 mit +26,25% internem Zinsfuß rausgegangen. Nach dem extrem schwachen letzten Jahr pendelt sich der mehrjährige Schnitt wieder auf statistischem Mittelmaß ein. Erwartungsgemäß, möchte man sagen. Also alles gut im Depot und Grüße an Nvidia. Gute Arbeit, Leute!

WebAssembly Experiment

von Christoph

Schon länger wollte ich mal etwas mit WebAssembly machen. Number crunching und performance-kritische Anwendung im Browser? Da bin ich dabei! Leider ist mir dazu nichts Realitätsnahes eingefallen (die klassische Schwierigkeit, wenn man zu einer Lösung das Problem sucht). Ich habe überlegt, ob man finanzmathematisch etwas implementieren könnte, aber über gleitende Durchschnitte oder Bezier-Splines mit 1000 Stützpunkten lacht sich ein Ryzen-Prozessor doch tot. Die üblichen Verdächtigen funktionieren locker in JavaScript.

Also habe ich das Game of Life von John H. Conway nochmal rausgekramt. Wie man das eben so macht, wenn man einfache Algorithmen auf größeren Datenmengen ausprobieren will. WebAssemblies (wasm) kann man in vielen Sprachen erzeugen. Ich habe es mit AssemblyScript probiert. Der Trick daran ist, dass man das auch nach JavaScript übersetzen kann - wichtig für Vergleiche. Aber hier erstmal das Ergebnis: der Evolutionsschritt findet in WebAssembly statt, das Rendering in JavaScript, denn WebAssembly hat keinen Zugriff auf das HTML DOM. Also bekommt es das Spielfeld als typisiertes Array und gibt die nächste Generation zurück. JavaScript packt das dann in ein Canvas.

Game of Life Screenshot

Nerd-Hinweise: Ein Klick mit der linken Maustaste platziert einen sogenannten Gleiter, ein Klick mit der rechten Maustaste eine Gleiterkanone. Die Simulation wird gedrosselt auf rund 10 Generationen pro Sekunde. Wenn die Evolution zum Erliegen kommt, einfach die Seite neu laden, um das Spielfeld zu resetten.

Und hat sich der ganze Spaß nun gelohnt? Als Lernerfahrung schon, aus Performance-Sicht leider nicht. Für die Benchmark habe ich 1000 Generationen ungedrosselt laufen lassen, jeweils ohne Rendering, damit hier nicht die Grafikkarte oder die Rendering-Engine vom Browser dazwischen funkt. Es sollte die meiste Rechenzeit im Game-of-Life-Algorithmus verbracht werden und nicht in der Browser-Infrastruktur. Ich war vom Ergebnis so verblüfft, dass ich in zwei weiteren Browsern gegenprüfen musste. WebAssembly ist signifikant langsamer als JavaScript.

Firefox 110 Edge 110 Chrome 110
WebAssembly 4030 ms 10386 ms 15083 ms
JavaScript 1019 ms 1096 ms 1077 ms

Ich vermute, das Problem ist zu sehr datengebunden. Die Übergabe der Rohdaten (nach WebAssembly und wieder raus, marshalling) ist teurer als wirklich mit den Daten etwas zu tun (der Algorithmus). Das Game of Life mit mehr als 100000 Feldern ist immer noch zu anspruchslos, um damit irgendwelche Optimierungen in verschiedenen Programmiersprachen und Runtimes zu machen.

Also Fazit: WebAssembly lohnt sich aus Performance-Sicht nicht pauschal. Vermutlich eher sehr selten. Ich denke, das ist etwas, wenn man existierenden Code in C++ oder Rust hat (Codecs, Krypto, Runtimes). Dann kann man den über Ecken auch im Browser ausführen. Wenn man eh neu entwickelt, kann man das auch direkt in JavaScript tun. Damit bin ich mir nicht mehr sicher, ob WebAssembly nicht nur ein modernes Flash oder Silverlight ist. Na mal sehen, ob da im Jahr 2030 noch ein Hahn nach kräht.

Programmiertes Logo

von Christoph

Mir ist kürzlich aufgefallen, dass mein vor etwa 20 Jahren gebautes Logo seit ungefähr 10 Jahren nicht mehr zeitgemäß ist. Leider bin ich auch nie richtig grün mit Bildbearbeitungsprogrammen geworden. Ich glaube ich hatte das Logo deswegen seinerzeit auch bereits mit POV-Ray gerendert, also quasi programmiert. Auf diese Art wollte ich mich auch an einem neuen Logo probieren. Ich habe mich dieses Mal für SVG (skalierbare Vektorgrafik) entschieden, weil ich es mit einem Texteditor manipulieren kann oder mit einem Programm, das Texte manipuliert.

Erste Idee: Es sollten idealerweise meine Initialen CS enthalten sein. Nun fällt auf, dass der obere Bogen des S ja schon ein C ist. Man muss das eine Zeichen innerhalb des anderen nur irgendwie sichtbar machen. Offensichtliche zweite Idee: andere Farbe! Ok, aber noch etwas subtiler wäre schön, zum Beispiel in der Geometrie. Geometrie? Geometrie? Da war doch was! Ich bin ja ein Fan von Mathematik im Allgemeinen und linearer Algebra im Besonderen. Außerdem glaube ich, dass visuelle Ästhetik unter anderem aus Mathematik kommt (Symmetrien, goldener Schnitt und Fraktale zum Beispiel).

Also sollte das S mit dem eingebetteten C irgendwie schlau zerschnitten werden. Und hier kommt wieder die Computergrafik ins Spiel. Ich mag außerdem 3D-Renderings und Drahtgittermodelle und an dieser Stelle wird es extrem: ich habe einen 3D-Software-Renderer nach SVG geschrieben - also ein Programm, dem man Dinge aus 3D-Koordinaten (x, y, z) reingibt und das zweidimensionales SVG (x, y) ausgibt. Ganz ohne DirectX, OpenGL und Vulkan, stattdessen mit Modell-, Ansicht- und Projektionsmatrix, perspektivischer Division und Bildschirm-Transformation. Lange Rede kurz: Ich habe ein animierbares Octahedron (Achtkant) hinter das S gepackt. Und damit ergibt sich ein "natürlicher" Schnitt in der Mitte.

Logo-Grafik

Die Schriftart habe ich bei Google Fonts gesucht und gefunden. Als MINT’ler sollte es für mich nur einigermaßen futuristisch aussehen. Das Fundstück habe ich im True Type Font (TTF) Format heruntergeladen und dort das S als Pfad-Spezifikation extrahiert. Das ergibt also:

  1. 3D-Octahedron nach 2D-SVG rendern.
  2. Darüber bündig den extrahierten S-Pfad legen (verschieben und skalieren bis es passt).
  3. Mit einem Texteditor den S-Pfad in zwei Pfade zerlegen sowie verschieden einfärben.
  4. Puh. Und als weiteren Spaß auch noch eine Animation integrieren, damit man sieht, dass es eigentlich 3D gemeint ist.

Mit dem Ergebnis bin ich als Nicht-Grafiker zufrieden. Es ist zeitgemäß flach (wenig Details, keine Schattierungen) und funktioniert in Groß, Klein (als Icon) und sogar animiert. Ah, und es ist nicht gemalt sondern programmiert.

Marktperformance 2022

von Christoph

Dies ist die Fortsetzung meines Marktrückblicks von 2021, der wiederum eine Fortsetzung des Marktrückblicks von 2020 ist. Ich hatte es letztes Jahr schon beschrien: die Börsenentwicklung war da so gut, dass statistisch gesehen mal deutlich etwas in Abwärtsrichtung passieren musste.

Und naja, was soll ich sagen? Wie niemandem entgangen sein dürfte, ging es abwärts. Bereinigt um Zu- und Abflüsse waren es in meinem Depot negative 19% Performance (exklusive Dividenden, die den Verlust noch leicht abmildern). Finanzmathematisch dürfte es sich bei meiner Berechnungsmethode um den internen Zinsfuß oder einen Verwandten davon handeln.

Gewinn-Verlust-Chart-2022

Wie üblich und auch schon beim Corona-Crash 2020 habe ich die Gelegenheit zum außerordentlichen Nachkaufen genutzt. Tatsächlich stehen in diesem Jahr ausschließlich Nachkäufe in der Bilanz. Keine neuen Positionen und auch keine Verkäufe. Ich habe nirgends das Vertrauen verloren. Es ist es mir auch lieber, dass es jetzt kracht als später, denn beim vermeintlich Unvermeidlichen bin ich ungeduldig (Achtung: ich rechne Geduld in Quartalen, nicht in Stunden oder Tagen). Jetzt müsste man nur noch wissen, wann es überstanden ist. Zusammen mit meinem alten Kumpel - der Statistik - gehe ich insgesamt von 6 bis 12 mauen Quartalen aus.

War 2022 also ein Reinfall, das erste von mehreren verlorenen Jahren? Nein. Abgesehen von der Beseitigung meines statistischen Unbehagens war es Kaufgelegenheit. Netto bin ich am Ende ungefähr bei 0 rausgekommen, das heißt ich habe Kursrückgänge durch Zukäufe kompensiert, jedoch nicht überkompensiert (dafür hatte ich dann doch nicht genügend Liquidität). Somit war es das erste Mal, dass mein Depot in absoluten Zahlen auf Jahressicht nicht gewachsen ist (ich bin seit 2014 an der Börse aktiv). Jedoch sehe ich die diesjährigen Zuflüsse als rabattierte Grundsteine für späteres Wachstum oder wie André Kostolany es ausdrückte: »Wer die Aktien nicht hat, wenn sie fallen, hat sie auch nicht, wenn sie steigen.«.

Einfacher Ausbruch

von Christoph

Man sieht in der Software-Entwicklung immer wieder, dass die Leute eine technische Lösung einführen wollen und dann ihr Problem darauf anpassen (technology driven development). Wer kann es den Ingenieuren verdenken? Technologien machen Spaß, halten kreativ, schaffen Arbeit. Je komplexer desto mehr. So kommen Firmen dann zu Softwaresystemen, die am tatsächlichen Bedarf um ihrer selbst willen geschmeidig vorbei­laufen. Weil ja das Problem erst noch an die Lösung angepasst werden muss, dieser Schritt dann aber nicht mehr gegangen wird, falls er denn überhaupt möglich ist.

Warum erzähle ich das? Nun, ich habe das in meiner Freizeit natürlich auch so gemacht. Ich wollte mal wieder etwas mit Computergrafik, irgendwas mit Shadern entwickeln, also habe ich mir die Probleme SameGame, Ballout und Snake geschaffen.

Jetzt war es aber mal an der Zeit, dem Minimalismus zu huldigen. Nehmen wir an, wir haben die Spielidee und wählen davon ausgehend die Werkzeuge! In diesem Fall ist mein Problem ein Breakout-Klon und meine Lösung ohne prozedurale 3D-Geometrie, Beleuchtungsberechnung und Texturen. Einfach nur Rechtecke, Kreise und etwas Vektormathematik. Entwicklergolf sozusagen - wer die wenigsten Züge braucht, gewinnt.

Bildschirmfoto Breakout

Wenn man das so angeht, kommt schnell heraus, dass man die ganze Grafikkarten-Magie überhaupt nicht benötigt. Das ist auch irgendwie klar, es ging schon 1976 ohne. Man schreibt 2022 natürlich auch nicht mehr Assembler, aber man kann mal versuchen, sich auf die Bordmittel, in diesem Fall von MS Windows, zu beschränken. Es ist zugegebenermaßen etwas Augenwischerei: MS Windows ist, wenn man so will, die fetteste Abhängigkeit, die man sich überhaupt in ein Projekt holen kann. Für Spiele ist das meiner Ansicht nach okay und die Grundannahme ist hierbei, dass die zehntausenden Entwickler bei Microsoft ihre milliardenfach ausgerollte Komplexität einigermaßen im Griff haben. Hier also der Code-Umfang von Breakout in Direct2D für MS Windows.

D:\Projects\Games [master]> cloc.exe .\Breakout\
      35 text files.
      35 unique files.
      30 files ignored.

github.com/AlDanial/cloc v 1.90  T=0.10 s (235.4 files/s, 20617.1 lines/s)
-------------------------------------------------------------------------------
Language                     files          blank        comment           code
-------------------------------------------------------------------------------
C++                              5            206             47            778
XML                              7              0              0            361
C/C++ Header                     8             65             23            204
Windows Resource File            1             51             63            163
JSON                             2              0              0             53
-------------------------------------------------------------------------------
SUM:                            23            322            133           1559
-------------------------------------------------------------------------------

Und schließlich die Downloads: Zip (32 Bit) | Zip (64 Bit). Wie immer gilt: einfach entpacken und ausprobieren, keine Installation, keine Systemveränderungen.

Marktperformance 2021

von Christoph

Dies ist die Fortsetzung meines Marktrückblicks von 2020. Es lief 2021 sehr gut. Beängstigend gut. So gut, dass statistisch gesehen die nächsten Jahre ziemlich mau ausfallen müssen damit der langfristige Mittelwert wieder passt. Ich habe lange überlegt, wie die Veränderung von 34% zu interpretieren ist. Wertsteigerung oder doch eher Kaufkraftverlust (Inflation)?

Da ich kein Volkswirt bin, muss ich mir hier mit einfacher Laienlogik helfen. Wertzuwachs hat für mich etwas von Leistung. Man hat eine besonders gute Strategie (Auswahl, Timing oder beides) und schlägt damit den Markt (dollargehandelter thesaurierender MSCI World dieses Jahr in € bei 32,6%). Inflation passiert einfach, egal was man macht. Bezüglich ersterem hatte ich ja letztes Jahr den tollen Plan, immer wieder nachzukaufen. Das war sicherlich richtig. Aber was man kauft, war im wesentlichen bedeutungslos. 2021 war es nur wichtig, breit investiert zu sein. War ich. Ergo handelte es sich um massive (Vermögenspreis-)Inflation.

Gewinn-Verlust-Chart-2021

Die Erkenntnis, dass Stock-Picking zu viel Aufwand für zu wenig Ertrag ist, reifte bei mir schon länger. Deswegen habe ich es dieses Jahr weitestgehend aufgegeben. Im Gegenteil, ähnlich wie bei Softwarekomplexität, glaube ich nun auch für mein Depot: einfacher ist besser. Werte, die zu lange unter-performed haben (und von denen ich nicht mehr überzeugt bin), habe ich deswegen in den MSCI World umgeschichtet. Einzelwerte, die gut liefen (zum Beispiel MSFT, NVDA, PG), habe ich natürlich laufen lassen. Ich bin jetzt aber auch nicht aktiver Rebalancer. Mein Plan für 2022 ist, den relativen Anteil der Einzelwerte durch Aufblähen der ETFs (via Zuflüsse) zu reduzieren. An den nun insgesamt 12 Positionen in meinem Depot will ich festhalten.

Ein paar Worte noch zu Anleihen. Ich habe das jetzt in 8 Jahren 4 mal probiert und bin nur einmal mit ganz wenig Gewinn da rausgegangen. Ok, die Verluste waren auch ganz wenig, aber nach meiner Erfahrung sind Anleihen keine sichere Kiste, die in jedes Depot gehören. Wenn eh Verluste nicht ausgeschlossen werden können, kann ich auch gleich defensive Aktien (Nestlé) oder ETFs nehmen. Also irgendwas habe ich hier nicht verstanden. Und ich geb's auch auf - Anleihen fasse ich nicht mehr an.

Die Ballspiel-Trilogie

von Christoph

»Wann hast du eigentlich zuletzt einen Arkustangens benutzt?«
»Na letzte Woche!«

Ja okay, ich gebe es zu: davor auch einige Jahre nicht mehr. Kürzlich habe ich es gebraucht, um den Winkel zwischen einem Fixpunkt und dem Mauszeiger zu bestimmen. Konkreter den Winkel eines am Ende fixierten virtuellen Kanonenrohrs und seiner beweglichen Mündung (gemessen zum Horizont).

Der Leser ahnt es schon. Ein neues Spiel! Und ich nenne es Ballout. Es ist im wesentlichen ein Klon von Puzzle Bobble (manchmal auch Bust a Move), ich habe es nur nicht so getauft, um nicht in irgendwelche markenrechtlichen Schusslinien zu geraten. Es basiert wieder einmal auf der von mir selbst entwickelten SameGame-Engine und enthält damit auch eine annehmbare physikalische Simulation.

Nach SameGame und Snake ist das nun schon das dritte Spiel auf dieser Technologie-Basis. Damit hat sich die Wiederverwendung wohl gelohnt - und natüüürlich war es von Anfang an als Trilogie geplant. Komplexitätsmäßig siedelt sich Ballout knapp über Snake an. Die Logik ist eben nicht übermäßig extravagant wenn man die Physik und Grafik bereits einmal vorbereitet hat.

Und jetzt nicht lange fackeln! Alle Spiele der Trilogie unter MS Windows ausprobieren: Zip (32 Bit) | Zip (64 Bit)