Signed Distance Fields (SDFs) wurden in diesem Artikel als schnelle Lösung vorgestellt, um eine auflösungsunabhängige Schriftwiedergabe durch Valve zu erzielen .
Ich habe bereits die Valve-Lösung im Einsatz, möchte aber die Schärfe um Ecken erhalten. Valve gibt an, dass mit seiner Methode scharfe Ecken erzielt werden können, indem zweite Texturkanäle UND-verknüpft mit dem Basiskanal verwendet werden. Es fehlt jedoch eine Erläuterung, wie dieser zweite Kanal erzeugt werden würde.
Tatsächlich wurden in diesem Dokument viele Implementierungsdetails ausgelassen.
Ich würde gerne wissen, ob jemand von Ihnen mir eine Anweisung geben kann, wie man SDFs mit scharfen Ecken rendern kann.
texture
signed-distance-field
font-rendering
Felipe Lira
quelle
quelle
Antworten:
Adam Simmons hat in diesem Bereich interessante Arbeit geleistet. Ich weiß nicht genau, wie er es erreicht, aber sein SDF-basiertes Vektor-Rendering ist das schärfste, das ich außerhalb von Valve in der Praxis gesehen habe. http://twitter.com/adamjsimmons/status/611677036545863680
quelle
EDIT: Bitte sehen Sie meine andere Antwort mit einer konkreten Lösung.
Genau dieses Problem habe ich vor über einem Jahr für meine Masterarbeit gelöst. Im Valve-Artikel wird gezeigt, dass Sie zwei Distanzfelder UND-verknüpfen können, um dies zu erreichen. Dies funktioniert, solange Sie nur eine konvexe Ecke haben. Für konkave Ecken benötigen Sie auch die ODER-Operation. Dieser Typ hat tatsächlich ein undurchsichtiges System entwickelt, um mit vier Texturkanälen zwischen den beiden Operationen umzuschalten.
Es gibt jedoch eine viel einfachere Operation, die je nach Situation UND und ODER erleichtert, und dies ist die Grundidee meiner These: der Median von drei . Im Grunde genommen verwenden Sie genau drei Kanäle (ideal für RGB), die vollständig austauschbar sind, und kombinieren sie mithilfe der Median-Operation (wählen Sie den Mittelwert aus den drei).
Um Antialiasing zu ermöglichen, arbeiten wir nicht nur mit Booleschen Werten, sondern mit Gleitkommawerten. Die UND-Verknüpfung wird zum Minimum und das ODER zum Maximum von zwei Werten. Der Median von drei kann in der Tat beides: Wenn a < b für ( a , a , b ) ist, ist der Median das Minimum und für ( a , b , b ) das Maximum.
Der Rendering-Prozess ist immer noch extrem einfach. Der gesamte Fragment-Shader einschließlich Antialiasing kann ungefähr so aussehen:
Der einzige Unterschied zur ursprünglichen Methode besteht also darin, den Median direkt nach dem Abtasten der Textur zu berechnen. Sie müssen jedoch die Medianfunktion implementieren, die mit nur 4 min / max-Operationen durchgeführt werden kann .
Nun ist natürlich die Frage, wie ich ein solches dreikanaliges Distanzfeld aufbaue.Und das ist der schwierige Teil. Der naheliegendste Ansatz, den ich am Anfang gewählt habe, war, eine Zerlegung der Eingabeform / Glyphe in drei Komponenten durchzuführen und dann aus jeder ein herkömmliches Distanzfeld zu erzeugen. Die Regeln für diese Zerlegung sind nicht so kompliziert. Erstens ist der Bereich mit mindestens 2 von 3 Kanälen innen. Wenn Sie sich dies als RGB-Farbkanäle vorstellen, müssen die konvexen Ecken aus einer Sekundärfarbe bestehen und die beiden Primärkomponenten nach außen fortgesetzt werden. Konkave Ecken sind die Umkehrung: Zwei Sekundärfarben umschließen ihre gemeinsame Primärfarbe, und der Keil zwischen den beiden nach innen verlaufenden Kanten ist weiß. Ich habe auch festgestellt, dass eine gewisse Polsterung erforderlich ist, wenn sich zwei Primär- oder zwei Sekundärfarben berühren würden, um Artefakte zu vermeiden (z. B. im mittleren Strich des "N").
Das folgende Bild ist eine Beispielzerlegung, die vom Programm aus meiner Diplomarbeit generiert wurde:
Dieser Ansatz hat jedoch einige Nachteile. Eine davon ist, dass die Spezialeffekte wie Konturen und Schatten nicht mehr richtig funktionieren. Glücklicherweise habe ich mir auch eine zweite, viel elegantere Methode ausgedacht, die die Distanzfelder direkt generiert und sogar alle grafischen Effekte unterstützt. Es ist auch in meiner Diplomarbeit enthalten und somit auch über ein Jahr alt. Ich werde im Moment keine weiteren Details angeben, da ich gerade einen Artikel schreibe, der diese zweite Technik ausführlich beschreibt, aber ich werde ihn hier veröffentlichen, sobald er fertig ist.
Hier ist ein Beispiel für den Qualitätsunterschied. Die Texturauflösung ist in jedem Bild gleich, aber das linke verwendet eine reguläre Textur, das mittlere ein normales Distanzfeld und das rechte mein dreikanaliges Distanzfeld. Der Leistungsaufwand ist nur der Unterschied zwischen dem Abtasten einer RGB-Textur und einer monochromen Textur.
quelle
Entschuldigen Sie das lange Warten, aber es hat sich gezeigt, dass der Veröffentlichungsprozess einige Zeit in Anspruch nehmen wird, obwohl der Artikel, den ich versprochen habe, im Grunde genommen vollständig ist. Daher habe ich stattdessen ein Open-Source-Programm mit meinem neuen Mehrkanal-Entfernungsfeldkonstruktionsalgorithmus msdfgen erstellt , das Sie jetzt ausprobieren können.
Es ist auf GitHub verfügbar: https://github.com/Chlumsky/msdfgen
(Ich bin neu in diesem Bereich, also lass es mich bitte wissen, wenn irgendetwas mit dem Repository nicht stimmt.)
Jemand fragte auch, wie es sich mit einem größeren monochromen Distanzfeld vergleichen lässt. Hier ist ein Anhaltspunkt für den Qualitätsunterschied. Es hängt jedoch wirklich von der jeweiligen Schriftart ab, und ich würde nicht sagen, dass es die zusätzlichen Daten immer wert ist.
quelle
Ziemlich interessant! Ich bin der Autor des von Ventilen signierten Distanzpapiers. Es tut uns leid, dass die Implementierungsdetails etwas spärlich sind. Ich habe nur das Zweikanal-Beispiel als zukünftige Arbeit aufgenommen - ich hatte keinen Generator. Ich dachte, es wäre eine vernünftige Taktik, eine hochauflösende SDF zu generieren und dann basierend auf dem Gradientenwinkel der SDF zu segmentieren. Aber ich bin nie dazu gekommen. Jedes Mehrkanalschema muss gegen die Verwendung von Einzelkanaldaten mit höherer Auflösung und gleichem Speicherbedarf abgewogen werden, um die Vergrößerungsverhältnisse zu erzielen, die Ihre App benötigt.
quelle
Ich bin kein Experte auf diesem Gebiet, aber Sie könnten zumindest theoretisch in der Lage sein, scharfe Ecken in einem monochromatischen Pseudo-SDF beizubehalten, wenn Sie entweder einen bilateralen Filter oder einen direktionalen bikubischen Filter anstelle eines standardmäßigen bilinearen Filters verwenden. Neben dem offensichtlichen Vorteil, Speicherplatz zu sparen, können Sie auch mehrere Kanäle für mehrfarbige SDF-Abziehbilder verwenden.
Wenn es Ihnen nichts ausmacht, einen zweiten Kanal zu verwenden, können Sie auch versuchen, einen Kanal für die horizontale Entfernung und einen anderen für die vertikale Entfernung zu verwenden und die Textur mithilfe einer Laplace-Energiepyramide (Difference of Laplacean, DoL) so zu komprimieren, dass redundante Informationen verloren gehen nicht aufgezeichnet werden.
Eine dritte und letzte theoretische Lösung wäre das Experimentieren mit einer hexagonal abgetasteten Textur über Array-Set-Adressierung.
Leider habe ich derzeit keine Möglichkeit, meine Ideen zu testen, und konnte keine Dokumente finden, die etwas Ähnliches zu meinen Ideen beschreiben oder testen. Ich werde in Kürze alle relevanten Artikel verlinken, in denen ich meine Informationen / Ideen erhalten habe.
quelle