Was ist der Stand der Technik für das Rendern von Text in OpenGL ab Version 4.1? [geschlossen]

199

Es gibt bereits eine Reihe von Fragen zum Rendern von Text in OpenGL, z.

Meistens wird jedoch das Rendern strukturierter Quads mithilfe der Pipeline mit festen Funktionen diskutiert. Sicherlich müssen Shader einen besseren Weg finden.

Ich bin nicht wirklich besorgt über die Internationalisierung, die meisten meiner Zeichenfolgen sind Plot-Tick-Labels (Datum und Uhrzeit oder rein numerisch). Die Diagramme werden jedoch mit der Bildschirmaktualisierungsrate neu gerendert, und es kann ziemlich viel Text vorhanden sein (nicht mehr als ein paar tausend Glyphen auf dem Bildschirm, aber genug, um das hardwarebeschleunigte Layout zu verbessern).

Was ist der empfohlene Ansatz für das Rendern von Text mit modernem OpenGL? (Das Zitieren vorhandener Software unter Verwendung des Ansatzes ist ein guter Beweis dafür, dass sie gut funktioniert.)

  • Geometrie-Shader, die z. B. Position und Ausrichtung sowie eine Zeichenfolge akzeptieren und strukturierte Quads ausgeben
  • Geometrie-Shader, die Vektorschriftarten rendern
  • Wie oben, jedoch stattdessen Tessellation-Shader verwenden
  • Ein Compute-Shader für die Rasterung von Schriftarten
Ben Voigt
quelle
10
Ich bin nicht in der Lage, auf dem neuesten Stand der Technik zu antworten, da ich heutzutage hauptsächlich OpenGL ES-orientiert bin, aber das Tessellieren eines TTF mit dem GLU-Tesselator und das Senden als Geometrie über die alte Pipeline mit fester Funktionalität und Kerning, berechnet auf CPU, lieferte gute visuelle Ergebnisse für Anti -aliasing Hardware und gute Leistung auf ganzer Linie noch vor fast einem Jahrzehnt. So können Sie nicht nur mit Shadern einen „besseren“ Weg finden (natürlich abhängig von Ihren Kriterien). FreeType kann Bezier-Glyphengrenzen und Kerning-Informationen ausspucken, sodass Sie zur Laufzeit live von einem TTF aus arbeiten können.
Tommy
QML2 (von Qt5) macht einige interessante Tricks mit OpenGL- und Distanzfeldern beim Rendern von Text: blog.qt.digia.com/blog/2012/08/08/native-looking-text-in-qml-2
mlvljr
Damit ich es nicht wieder verliere, ist hier eine Bibliothek, die die Distanzfeldmethode von Valve implementiert. code.google.com/p/glyphy Ich habe es nicht ausprobiert. Vielleicht auch einen Blick wert: code.google.com/p/signed-distance-field-font-generator
Timmmm
7
Dieses "Off-Topic" ist der Fluch des Stapelüberlaufs. Ernsthaft?
Nikolaos Giotis
1
eine naivere
Ciro Santilli 1 冠状 病 病 六四 法轮功

Antworten:

202

Das Rendern von Konturen bleibt, sofern Sie nicht nur ein Dutzend Zeichen insgesamt rendern, aufgrund der Anzahl der Scheitelpunkte, die pro Zeichen zur Annäherung an die Krümmung benötigt werden, ein "Nein". Obwohl es Ansätze zur Bewertung von Bezierkurven im Pixel-Shader gegeben hat, leiden diese darunter, dass sie nicht leicht antialiasiert werden können, was bei Verwendung eines Quad mit Entfernungskartentextur trivial ist, und die Bewertung von Kurven im Shader ist immer noch rechenintensiver als erforderlich.

Der beste Kompromiss zwischen "schnell" und "Qualität" sind immer noch strukturierte Quads mit einer signierten Distanzfeldtextur. Es ist etwas langsamer als ein normales strukturiertes Quad, aber nicht so sehr. Die Qualität hingegen liegt in einem ganz anderen Stadion. Die Ergebnisse sind wirklich beeindruckend, es ist so schnell wie möglich und Effekte wie Glühen lassen sich ebenfalls ganz einfach hinzufügen. Außerdem kann die Technik bei Bedarf problemlos auf ältere Hardware heruntergestuft werden.

Siehe das berühmte Ventilpapier für die Technik.

Die Technik ähnelt konzeptionell der Funktionsweise impliziter Oberflächen (Metabälle und dergleichen), erzeugt jedoch keine Polygone. Es läuft vollständig im Pixel-Shader und verwendet die von der Textur abgetastete Entfernung als Abstandsfunktion. Alles über einem gewählten Schwellenwert (normalerweise 0,5) ist "in", alles andere ist "out". Im einfachsten Fall bewirkt das Festlegen des Alpha-Test-Schwellenwerts auf 0,5 bei 10 Jahre alter, nicht shaderfähiger Hardware genau dies (allerdings ohne Spezialeffekte und Antialiasing).
Wenn Sie der Schriftart etwas mehr Gewicht hinzufügen möchten (faux fett), reicht ein etwas kleinerer Schwellenwert aus, ohne eine einzelne Codezeile zu ändern (ändern Sie einfach Ihre Uniform "font_weight"). Für einen Glow-Effekt betrachtet man einfach alles über einer Schwelle als "in" und alles über einer anderen (kleineren) Schwelle als "out, but in glow" und LERPs zwischen den beiden. Antialiasing funktioniert ähnlich.

Durch die Verwendung eines vorzeichenbehafteten 8-Bit-Abstandswerts anstelle eines einzelnen Bits erhöht diese Technik die effektive Auflösung Ihrer Texturabbildung in jeder Dimension um das 16-fache (anstelle von Schwarzweiß werden alle möglichen Schattierungen verwendet, sodass wir das 256-fache haben Informationen, die denselben Speicher verwenden). Aber selbst wenn Sie weit über das 16-fache vergrößern, sieht das Ergebnis immer noch akzeptabel aus. Lange gerade Linien werden irgendwann etwas wackelig, aber es gibt keine typischen "blockartigen" Abtastartefakte.

Sie können einen Geometrie-Shader verwenden, um die Quads aus Punkten zu generieren (Busbandbreite reduzieren), aber ehrlich gesagt sind die Gewinne eher gering. Gleiches gilt für das instanziierte Rendern von Zeichen, wie in GPG8 beschrieben. Der Aufwand für die Instanzierung wird nur amortisiert, wenn Sie viel Text zeichnen müssen. Die Gewinne stehen meiner Meinung nach in keinem Zusammenhang mit der zusätzlichen Komplexität und Nicht-Herabstufbarkeit. Außerdem sind Sie entweder durch die Anzahl der konstanten Register begrenzt oder müssen aus einem Texturpufferobjekt lesen, das für die Cache-Kohärenz nicht optimal ist (und die Absicht bestand darin, zunächst zu optimieren!).
Ein einfacher, einfacher alter Vertex-Puffer ist genauso schnell (möglicherweise schneller), wenn Sie den Upload etwas früher planen und auf jeder Hardware ausgeführt werden, die in den letzten 15 Jahren erstellt wurde. Und es ist weder auf eine bestimmte Anzahl von Zeichen in Ihrer Schriftart noch auf eine bestimmte Anzahl von Zeichen beschränkt, die gerendert werden sollen.

Wenn Sie sicher sind, dass Ihre Schriftart nicht mehr als 256 Zeichen enthält, sollten Texturarrays eine Überlegung wert sein, um die Busbandbreite auf ähnliche Weise wie beim Generieren von Quads aus Punkten im Geometrie-Shader zu reduzieren. Bei Verwendung einer Array-Textur haben die Texturkoordinaten aller Quads identische, konstante sund tkoordinierte Koordinaten und unterscheiden sich nur in der rKoordinate, die dem zu rendernden Zeichenindex entspricht.
Aber wie bei den anderen Techniken sind die erwarteten Gewinne auf Kosten der Inkompatibilität mit Hardware der vorherigen Generation gering.

Es gibt ein praktisches Tool von Jonathan Dummer zum Generieren von Entfernungstexturen: Beschreibungsseite

Update:
Wie kürzlich in Programmable Vertex Pulling (D. Rákos, "OpenGL Insights", S. 239) ausgeführt wurde, ist das programmgesteuerte Abrufen von Vertex-Daten aus dem Shader bei den neuesten GPU-Generationen nicht wesentlich länger. im Vergleich dazu, dasselbe mit der festen Standardfunktion zu tun.
Außerdem verfügen die neuesten GPU-Generationen über immer größere Allzweck-L2-Caches (z. B. 1536 kB bei nvidia Kepler), sodass das inkohärente Zugriffsproblem zu erwarten ist, wenn zufällige Offsets für die Quad-Ecken aus einer Puffertextur gezogen werden, die kleiner als a ist Problem.

Dies macht die Idee, konstante Daten (wie Quad-Größen) aus einer Puffertextur zu ziehen, attraktiver. Eine hypothetische Implementierung könnte daher PCIe- und Speicherübertragungen sowie GPU-Speicher mit einem Ansatz wie diesem auf ein Minimum reduzieren:

  • Laden Sie nur einen Zeichenindex (einen pro anzuzeigendem Zeichen) als einzige Eingabe in einen Scheitelpunkt-Shader hoch, der diesen Index gl_VertexIDweitergibt, und verstärken Sie diesen auf 4 Punkte im Geometrie-Shader, wobei der Zeichenindex und die Scheitelpunkt-ID (dies) weiterhin vorhanden sind wird "gl_primitiveID im Vertex-Shader zur Verfügung gestellt") als einziges Attribut und erfasst dies über Transformations-Feedback.
  • Dies ist schnell, da es nur zwei Ausgabeattribute gibt (Hauptengpass in GS) und es ansonsten in beiden Phasen nahe an "no-op" liegt.
  • Binden Sie eine Puffertextur, die für jedes Zeichen in der Schriftart die Scheitelpunktpositionen des strukturierten Quad relativ zum Basispunkt enthält (dies sind im Grunde die "Schriftartmetriken"). Diese Daten können auf 4 Zahlen pro Quad komprimiert werden, indem nur der Versatz des unteren linken Scheitelpunkts gespeichert und die Breite und Höhe des achsenausgerichteten Felds codiert werden (unter der Annahme, dass die Hälfte schwebt, sind dies 8 Bytes konstanter Puffer pro Zeichen - Eine typische 256-Zeichen-Schriftart könnte vollständig in 2 KB L1-Cache passen.
  • Legen Sie eine Uniform für die Grundlinie fest
  • Binden Sie eine Puffertextur mit horizontalen Offsets. Diese könnten wahrscheinlich sogar auf der GPU berechnet werden, aber es ist viel einfacher und effizienter für solche Dinge auf der CPU, da es sich um eine streng sequentielle Operation handelt und überhaupt nicht trivial ist (denken Sie an Kerning). Außerdem würde ein weiterer Rückkopplungsdurchlauf erforderlich sein, der ein weiterer Synchronisationspunkt wäre.
  • Beim Rendern der zuvor generierten Daten aus dem Rückkopplungspuffer zieht der Vertex-Shader den horizontalen Versatz des Basispunkts und die Offsets der Eckscheitelpunkte aus Pufferobjekten (unter Verwendung der primitiven ID und des Zeichenindex). Die ursprüngliche Scheitelpunkt-ID der übermittelten Scheitelpunkte ist jetzt unsere "primitive ID" (denken Sie daran, dass der GS die Scheitelpunkte in Quads umgewandelt hat).

Auf diese Weise könnte man die erforderliche Scheitelpunktbandbreite idealerweise um 75% reduzieren (amortisiert), obwohl nur eine einzige Linie gerendert werden könnte. Wenn man in der Lage sein möchte, mehrere Linien in einem Zeichenaufruf zu rendern, müsste man die Grundlinie zur Puffertextur hinzufügen, anstatt eine Uniform zu verwenden (wodurch die Bandbreitengewinne kleiner werden).

Selbst unter der Annahme einer Reduzierung um 75% - da die Scheitelpunktdaten zur Anzeige "angemessener" Textmengen nur etwa 50 bis 100 kB betragen (was praktisch Null ist)an eine GPU oder einen PCIe-Bus) - Ich bezweifle immer noch, dass die zusätzliche Komplexität und der Verlust der Abwärtskompatibilität die Mühe wirklich wert sind. Die Reduzierung von Null um 75% ist immer noch nur Null. Ich habe den oben genannten Ansatz zugegebenermaßen nicht ausprobiert, und es wären weitere Untersuchungen erforderlich, um eine wirklich qualifizierte Aussage zu treffen. Aber wenn nicht jemand einen wirklich erstaunlichen Leistungsunterschied nachweisen kann (mit "normalen" Textmengen, nicht mit Milliarden von Zeichen!), Bleibt mein Standpunkt, dass für die Scheitelpunktdaten ein einfacher, einfacher alter Scheitelpunktpuffer zu Recht gut genug ist als Teil einer "Lösung auf dem neuesten Stand der Technik" zu betrachten. Es ist einfach und unkompliziert, es funktioniert und es funktioniert gut.

Nachdem oben bereits auf " OpenGL Insights " verwiesen wurde , ist auch auf das Kapitel "2D-Formwiedergabe nach Entfernungsfeldern" von Stefan Gustavson hinzuweisen, in dem die Darstellung von Entfernungsfeldern ausführlich erläutert wird.

Update 2016:

Mittlerweile gibt es mehrere zusätzliche Techniken, die darauf abzielen, die bei extremen Vergrößerungen störenden Eckrundungsartefakte zu entfernen.

Ein Ansatz verwendet einfach Pseudo-Distanzfelder anstelle von Distanzfeldern (der Unterschied besteht darin, dass der Abstand der kürzeste Abstand nicht zum tatsächlichen Umriss, sondern zum Umriss oder einer imaginären Linie ist, die über die Kante hinausragt). Dies ist etwas besser und läuft mit der gleichen Geschwindigkeit (identischer Shader) und der gleichen Menge an Texturspeicher.

Ein anderer Ansatz verwendet den Median-of-Three in einer dreikanaligen Textur, die bei github verfügbar ist . Dies soll eine Verbesserung gegenüber den und / oder Hacks darstellen, die zuvor zur Behebung des Problems verwendet wurden. Gute Qualität, leicht, fast nicht merklich, langsamer, verbraucht aber dreimal so viel Texturspeicher. Außerdem sind zusätzliche Effekte (z. B. Glühen) schwieriger zu erzielen.

Schließlich ist das Speichern der tatsächlichen Bezierkurven, aus denen Zeichen bestehen, und das Auswerten in einem Fragment-Shader praktisch geworden , mit etwas schlechterer Leistung (aber nicht so sehr, dass es ein Problem darstellt) und atemberaubenden Ergebnissen selbst bei höchsten Vergrößerungen.
Eine WebGL-Demo zum Rendern eines großen PDF-Dokuments mit dieser Technik in Echtzeit finden Sie hier .

Damon
quelle
1
Sie sehen ziemlich gut aus (auch bei naiver Filterung und ohne Mipmapping, da Sie sehr kleine Texturen haben und die Daten gut interpolieren). Persönlich denke ich, dass sie in vielen Fällen sogar besser aussehen als das "echte", weil es keine Seltsamkeiten als Andeutungen gibt, die oft Dinge hervorbringen, die ich als "seltsam" empfinde. Zum Beispiel wird kleinerer Text nicht plötzlich ohne ersichtlichen Grund fett und springt auch nicht an Pixelgrenzen - Effekte, die Sie häufig bei "echten" Schriftarten sehen. Es mag historische Gründe dafür geben (1985 s / w-Anzeigen), aber heute ist es für mich unverständlich, warum es so sein muss.
Damon
2
Funktioniert und sieht gut aus, danke fürs Teilen! Für diejenigen, die HLSL Frag Shader Quelle wollen, siehe hier . Sie können dies für GLSL anpassen, indem Sie die clip(...)Zeile durch if (text.a < 0.5) {discard;}(oder text.a < threshold) ersetzen . HTH.
Ingenieur
1
Danke für das Update. Ich wünschte, ich könnte wieder abstimmen.
Ben Voigt
2
@NicolBolas: Sie scheinen nicht sehr sorgfältig gelesen zu haben. Beide Fragen werden in der Antwort erklärt. Kepler wird als Beispiel der "neuesten Generation" angegeben, es gibt keinen zweiten Durchgang (und es wird erklärt, warum), und ich erkläre, dass ich nicht glaube, dass die hypotetische Bandbreitenspartechnik spürbar schneller ist oder die Mühe überhaupt wert ist. Glaube bedeutet jedoch nichts - man müsste versuchen zu wissen (ich habe es nicht getan, da ich das Zeichnen "normaler" Textmengen in keiner Weise als Engpass betrachte). Es könnte sich dennoch lohnen, wenn man verzweifelt nach Bandbreite ist und "abnormale" Textmengen hat.
Damon
3
@NicolBolas: Du hast Recht mit diesem Satz, sorry. Es ist in der Tat etwas irreführend. Im vorherigen Absatz schrieb ich: "Man könnte dies wahrscheinlich sogar auf der GPU generieren, aber das würde Feedback und ... isnogud erfordern." - aber dann fälschlicherweise mit "den generierten Daten aus dem Rückkopplungspuffer" fortgefahren . Ich werde das korrigieren. Eigentlich werde ich das Ganze am Wochenende neu schreiben, damit es weniger zweideutig ist.
Damon
15

http://code.google.com/p/glyphy/

Der Hauptunterschied zwischen GLyphy und anderen SDF-basierten OpenGL-Renderern besteht darin, dass die meisten anderen Projekte die SDF in eine Textur abtasten. Dies hat alle üblichen Probleme, die die Probenahme hat. Dh. es verzerrt den Umriss und ist von geringer Qualität. GLyphy repräsentiert stattdessen die SDF unter Verwendung der tatsächlichen Vektoren, die an die GPU gesendet werden. Dies führt zu einer sehr hohen Renderqualität.

Der Nachteil ist, dass der Code für iOS mit OpenGL ES ist. Ich werde wahrscheinlich einen Windows / Linux OpenGL 4.x-Port erstellen (hoffentlich fügt der Autor jedoch eine echte Dokumentation hinzu).

Anzeigename
quelle
3
Jeder, der sich für GLyphy interessiert, sollte sich wahrscheinlich den Vortrag des Autors unter Linux.conf.au 2014 ansehen: youtube.com/watch?v=KdNxR5V7prk
Fizz
14

Die am weitesten verbreitete Technik sind immer noch strukturierte Quads. Im Jahr 2005 entwickelte LORIA jedoch sogenannte Vektortexturen, dh das Rendern von Vektorgrafiken als Texturen auf Grundelementen. Wenn man damit TrueType- oder OpenType-Schriftarten in eine Vektortextur konvertiert, erhält man Folgendes:

http://alice.loria.fr/index.php/publications.html?Paper=VTM@2005

Datenwolf
quelle
2
Kennen Sie Implementierungen mit dieser Technik?
Luke
2
Nein (wie in der Produktionsqualität), aber Kilgards Artikel (Link siehe meine Antwort unten) enthält eine kurze Kritik, die ich wie folgt zusammenfasse: noch nicht praktikabel. In diesem Bereich wurde mehr geforscht. Neuere Arbeiten, die von Kilgard zitiert wurden, umfassen research.microsoft.com/en-us/um/people/hoppe/ravg.pdf und uwspace.uwaterloo.ca/handle/10012/4262
Fizz
9

Ich bin überrascht, dass Mark Kilgards Baby NV_path_rendering (NVpr) von keinem der oben genannten erwähnt wurde. Obwohl seine Ziele allgemeiner sind als das Rendern von Schriftarten, kann es auch Text aus Schriftarten und mit Kerning rendern. Es erfordert nicht einmal OpenGL 4.1, ist aber derzeit eine Nur-Hersteller- / Nvidia-Erweiterung. Grundsätzlich werden Schriftarten in Pfade umgewandelt, glPathGlyphsNVdie von der freetype2-Bibliothek abhängen, um die Metriken usw. abzurufen. Anschließend können Sie auch mit glGetPathSpacingNVden allgemeinen Pfadwiedergabemechanismen von NVpr auf die Kerning-Informationen zugreifen und Text aus den pfad- "konvertierten" Schriftarten anzeigen. (Ich habe das in Anführungszeichen gesetzt, da es keine echte Konvertierung gibt, werden die Kurven unverändert verwendet.)

Die aufgezeichnete Demo für die Schriftarten von NVpr ist leider nicht besonders beeindruckend. (Vielleicht sollte jemand eine nach dem Vorbild der viel schickeren SDF-Demo machen , die man auf den Intertubes findet ...)

Der Vortrag zur NVpr-API-Präsentation 2011 für den Schriftarten-Teil beginnt hier und wird im nächsten Teil fortgesetzt . Es ist ein bisschen bedauerlich, wie diese Präsentation aufgeteilt ist.

Allgemeinere Materialien zu NVpr:

  • Nvidia NVpr Hub , aber einige Materialien auf der Zielseite sind nicht auf dem neuesten Stand
  • Siggraph 2012-Papier für die Gehirne der Pfad-Rendering-Methode, genannt "Schablone, dann Abdeckung" (StC); Das Papier erklärt auch kurz, wie konkurrierende Technologien wie Direct2D funktionieren. Die schriftbezogenen Bits wurden in einen Anhang des Papiers verbannt . Es gibt auch einige Extras wie Videos / Demos .
  • Präsentation der AGB 2014 für einen Aktualisierungsstatus; Kurz gesagt: Es wird jetzt von Googles Skia unterstützt (Nvidia hat den Code Ende 2013 und 2014 beigesteuert), das wiederum in Google Chrome und [meiner Meinung nach unabhängig von Skia] in einer Beta von Adobe Illustrator CC 2014 verwendet wird
  • die offizielle Dokumentation in der OpenGL-Erweiterungsregistrierung
  • USPTO hat Kilgard / Nvidia im Zusammenhang mit NVpr mindestens vier Patente erteilt, von denen Sie wahrscheinlich wissen sollten, falls Sie StC selbst implementieren möchten: US8698837 , US8698808 , US8704830 und US8730253 . Beachten Sie, dass damit etwa 17 weitere USPTO-Dokumente als "auch veröffentlicht als" verbunden sind, von denen die meisten Patentanmeldungen sind. Daher ist es durchaus möglich, dass von diesen mehr Patente erteilt werden.

Und da das Wort "Schablone" vor meiner Antwort keine Treffer auf dieser Seite hervorgebracht hat, scheint es, dass die Untergruppe der SO-Community, die an dieser Seite teilgenommen hat, insofern, als sie ziemlich zahlreich war, keine Kenntnis von tessellationsfreiem Schablonenpuffer hatte. basierte Methoden für das Rendern von Pfaden / Schriftarten im Allgemeinen. Kilgard hat einen FAQ-ähnlichen Beitrag im opengl-Forum, der möglicherweise beleuchtet, wie sich die tessellationsfreien Pfadwiedergabemethoden von Standard-3D-Grafiken unterscheiden, obwohl sie immer noch eine [GP] -GPU verwenden. (NVpr benötigt einen CUDA-fähigen Chip.)

Aus historischer Sicht ist Kilgard auch Autor des Klassikers "Eine einfache OpenGL-basierte API für texturabgebildeten Text", SGI, 1997 , der nicht mit dem schablonenbasierten NVpr verwechselt werden sollte, der 2011 debütierte.


Die meisten, wenn nicht alle neueren Methoden, die auf dieser Seite behandelt werden, einschließlich schablonenbasierter Methoden wie NVpr oder SDF-basierter Methoden wie GLyphy (auf die ich hier nicht weiter eingehen werde, da andere Antworten dies bereits behandeln), haben jedoch eine Einschränkung: Sie sind es Geeignet für die Anzeige großer Texte auf herkömmlichen Monitoren (~ 100 DPI) ohne Zacken auf jeder Skalierungsstufe, und sie sehen auch bei kleinen Abmessungen auf Retina-ähnlichen Displays mit hoher DPI gut aus. Sie bieten jedoch nicht vollständig das, was Microsoft Direct2D + DirectWrite Ihnen bietet, nämlich Hinweise auf kleine Glyphen auf Mainstream-Displays. (Eine visuelle Übersicht über Hinweise im Allgemeinen finden Sie beispielsweise auf dieser Typothek-Seite . Eine ausführlichere Ressource finden Sie auf antigrain.com .)

Mir sind keine offenen und produzierten OpenGL-basierten Dinge bekannt, die das tun können, was Microsoft im Moment mit Hinweisen kann. (Ich gebe zu, dass ich Apples OS X GL / Quartz-Interna nicht kenne, da Apple nach meinem besten Wissen nicht veröffentlicht hat, wie sie GL-basiertes Rendering von Schriftarten / Pfaden ausführen. Es scheint, dass OS X dies im Gegensatz zu MacOS 9 nicht tut überhaupt Hinweise geben, was manche Leute nervt .) Wie auch immer, es gibt ein Forschungspapier aus dem Jahr 2013, das sich mit Hinweisen über OpenGL-Shader befasst, die von Nicolas P. Rougier von INRIA geschrieben wurden. Es lohnt sich wahrscheinlich zu lesen, wenn Sie Hinweise von OpenGL benötigen. Während es den Anschein haben mag, dass eine Bibliothek wie freetype bereits die ganze Arbeit erledigt, wenn es um Hinweise geht, ist dies aus folgendem Grund, den ich aus dem Artikel zitiere, nicht der Fall:

Die FreeType-Bibliothek kann eine Glyphe mithilfe von Subpixel-Anti-Aliasing im RGB-Modus rastern. Dies ist jedoch nur die Hälfte des Problems, da wir auch eine Subpixel-Positionierung für eine genaue Platzierung der Glyphen erreichen möchten. Das Anzeigen des strukturierten Quad bei gebrochenen Pixelkoordinaten löst das Problem nicht, da es nur zu einer Texturinterpolation auf der Ebene ganzer Pixel führt. Stattdessen möchten wir eine genaue Verschiebung (zwischen 0 und 1) in der Subpixel-Domäne erreichen. Dies kann in einem Fragment-Shader erfolgen [...].

Die Lösung ist nicht gerade trivial, daher werde ich hier nicht versuchen, sie zu erklären. (Das Papier ist offen zugänglich.)


Eine andere Sache, die ich aus Rougiers Artikel gelernt habe (und die Kilgard anscheinend nicht berücksichtigt hat), ist, dass die vorhandenen Schriftfähigkeiten (Microsoft + Adobe) nicht nur eine, sondern zwei Kerning-Spezifikationsmethoden erstellt haben. Die alte basiert auf einer sogenannten Kern- Tabelle und wird vom Freetype unterstützt. Das neue heißt GPOS und wird nur von neueren Schriftbibliotheken wie HarfBuzz oder pango in der Welt der freien Software unterstützt. Da NVpr keine dieser Bibliotheken zu unterstützen scheint, funktioniert das Kerning mit NVpr für einige neue Schriftarten möglicherweise nicht sofort. Laut dieser Forumsdiskussion gibt es einige von denen, die anscheinend in freier Wildbahn leben .

Wenn Sie ein komplexes Textlayout (CTL) durchführen müssen , scheinen Sie derzeit mit OpenGL kein Glück zu haben, da dafür keine OpenGL-basierte Bibliothek zu existieren scheint. (DirectWrite hingegen kann CTL verarbeiten.) Es gibt Open-Source-Bibliotheken wie HarfBuzz, die CTL rendern können, aber ich weiß nicht, wie Sie sie dazu bringen würden, gut zu funktionieren (wie bei der Verwendung schablonenbasierter Methoden) OpenGL. Sie müssten wahrscheinlich den Klebercode schreiben, um die neu geformten Umrisse zu extrahieren und sie als Pfade in NVpr- oder SDF-basierte Lösungen einzuspeisen.

Fizz
quelle
4
Ich habe NV_path_rendering nicht erwähnt, da es sich um eine Erweiterung handelt, die von einem Anbieter entwickelt wurde, um die Sache noch schlimmer zu machen. Normalerweise versuche ich, Antworten nur für Techniken zu geben, die universell anwendbar sind.
Datenwolf
1
Nun, dem kann ich bis zu einem gewissen Grad zustimmen. Die Methode selbst ("Schablone, dann Abdeckung") ist eigentlich nicht schwer direkt in OpenGL zu implementieren, hat jedoch einen hohen Befehlsaufwand, wenn sie auf diese Weise naiv ausgeführt wird, da frühere schablonenbasierte Versuche endeten. Skia [via Ganesh] versuchte es pünktlich mit einer schablonenbasierten Lösung, gab sie aber laut Kilgrad auf. Die Art und Weise, wie es von Nvidia implementiert wird, eine Schicht darunter, die CUDA-Funktionen verwendet, macht es leistungsfähig. Sie könnten versuchen, StC selbst mit einer ganzen Reihe von EXT / ARB-Erweiterungen zu "manteln". Beachten Sie jedoch, dass Kilgard / Nvidia zwei Patentanmeldungen für NVpr haben.
Fizz
3

Ich denke, Ihre beste Wahl wäre es, Kairo-Grafiken mit OpenGL-Backend zu untersuchen.

Das einzige Problem, das ich bei der Entwicklung eines Prototyps mit 3.3-Kern hatte, war die veraltete Funktionsnutzung im OpenGL-Backend. Es war vor 1-2 Jahren, also könnte sich die Situation verbessert haben ...

Wie auch immer, ich hoffe, dass OpenGG-Grafiktreiber in Zukunft OpenVG implementieren werden.

Orhun
quelle