Dies ist eine Demonstration des Renderns von Text direkt in der GPU mit den von der Schriftart definierten Vektorumrissen.
Die Konturen einer Glyphe werden in eine Liste einzelner quadratischer Bezier -Kurven (definiert durch ihre Kontrollpunkte) umgewandelt, die in die GPU hochgeladen werden.
Für jede Glyphe wird ein Quad erzeugt und der Pixel -Shader bestimmt, ob sich jedes Pixel innerhalb oder außerhalb der Glyphe befindet. Zu diesem Zweck wird die Wickelzahl des Pixels berechnet, indem ein Strahl mit den Bezier -Kurven gekreuzt wird. An jeder Kreuzung tritt der Strahl entweder in den gefüllten Bereich ein oder verlässt sie durch die Richtung der Bezier -Kurve relativ zum Strahl. An jedem Ausgang wird die Wickelzahl um eins erhöht und bei jedem Eintrag wird die Wickelzahl um eins verringert. Nach Berücksichtigung aller Kreuzungen ist die Wicklungsnummer ungleich Null, wenn sich das Pixel im Umriss befindet.
Die Richtung der Strahlen spielt keine Rolle für diese Berechnung der Wicklungszahl, aber die Mathematik kann durch die Verwendung von Strahlen parallel zur X-Achse stark vereinfacht werden. Durch Subtrahieren der Probenposition von den Kontrollpunkten der Bezier -Kurven wird das Koordinatensystem so verschoben, dass der Ursprung des Strahls an ist
Um die Kreuzungen zwischen einem Strahl und einer einzelnen Bezier -Kurve zu finden, erinnern Sie sich daran, dass eine quadratische Bezier -Kurve durch die folgende Formel beschrieben wird (für Hintergrund zu Bezier -Kurven siehe Schönheit und Primer):
Nur die Y-Komponente einnehmen und den Zustand anwenden
Die neu angeordnet werden können in:
Damit es mit der quadratischen Formel gelöst werden kann:
Ersetzen
Die quadratische Gleichung kann Null, ein oder zwei Lösungen haben. Darüber hinaus eine Lösung
Zu diesem Zeitpunkt wurden die Kreuzungen zwischen der Strahl- und Bezier -Kurve identifiziert, müssen jedoch weiterhin als Eintritt oder Ausgang eingestuft werden. Die von Dobbie bereitgestellte Demo berechnet die Ableitung der Bezier -Kurve für jeden ausdrücklich
Daher überschreitet die Bezier-Kurve die x-Achse in einer festen Richtung in jeder Lösung und kombiniert mit der Konvention zur Ausrichtung der Kontur.
Ein anderer Ansatz zum Verständnis dieser Beziehung besteht darin, zu bemerken, dass aufgrund der verschiedenen in den Lösungen verwendeten Zeichen und der Quadratwurzel nicht negativ sind
Wenn der Parameter
Anti-Aliasing entlang der Strahlenrichtung wird durch Berücksichtigung eines Fensters der Größe eines Pixels um den Strahlenursprung implementiert. Wenn eine Kreuzung in dieses Fenster fällt, wird die Wickelzahl nur fraktional geändert, um die Abdeckung des Pixels zu berechnen. Das Bruchgewicht wird durch den Abstand vom linken Rand des Pixels bestimmt (dies steht im Einklang mit den nach rechts zeigen Strahlen). Durch die Betrachtung der einzelnen Abschnitte kann man sehen, dass dies die eindimensionale Abdeckung genau berechnet.
Beachten Sie, dass wir jetzt auch Schnittpunkte hinter dem Strahlenursprung in Betracht ziehen müssen, aber die Implementierung berechnet zunächst jede Schnittstelle mit der X-Achse und überprüft dann die X-Position, sodass es sich nicht viel ändert. Eine andere Denkweise darüber ist, dass die Erkrankung
Zur vollständigen Anti-Aliasing können wir mehrere Strahlen entlang verschiedener Richtungen verwenden (z. B. eine entlang der x-Achse und eine entlang der y-Achse).
Diese Art von Technik unterliegt Artefakten aus der begrenzten numerischen Präzision der schwimmenden Punktzahlen. Das Bild unten zeigt eine Instanz solcher Artefakte, wenn sie vollständig vergrenzt ist (und wissen, wo man nachsehen soll). Trotzdem habe ich festgestellt, dass diese Implementierung bereits numerisch stabil ist. Verbleibende Artefakte könnten mit dem Slug -Algorithmus beseitigt werden, der hier aufgrund des zugehörigen Patents nicht implementiert wird.
Diese Demo implementiert auch keine Leistungsoptimierungen (wie das Binden) und hat möglicherweise eine hohe GPU -Verwendung in einigen Szenarien und bei sehr komplexen Schriftarten.

Klonen Sie das Projekt rekursiv, um die Submodules für die Abhängigkeiten zu initialisieren (oder git submodule update --init wenn Sie bereits das Repo geklont haben):
git clone --recursive https://github.com/GreenLightning/gpu-font-rendering.git
cd gpu-font-rendering
# Note: CMake will create the build directory.
cmake -S . -B build
make -j8 --directory build
Unter Windows möchten Sie stattdessen möglicherweise CMAKE GUI und/oder Visual Studio verwenden.
Unter Linux müssen Sie möglicherweise zusätzliche Pakete für die OpenGL-Entwicklung installieren (z. B. sudo apt-get install xorg-dev libgl1-mesa-dev für Ubuntu).
./build/main
Das Programm erfordert, dass die Verzeichnisse der fonts und shaders im aktuellen Verzeichnis ihre Ressourcen laden. Wenn Sie nur ein schwarzes Fenster erhalten , ist dies höchstwahrscheinlich das Problem. Überprüfen Sie Ihr Arbeitsverzeichnis und überprüfen Sie die Konsole auf Fehler.
Getestet unter Windows 10, MacOS Monterey und Ubuntu 22.04.