Ich brauche eine Möglichkeit, auflösungsunabhängigen Text in meinem Spiel zu zeichnen. Das heißt, ich muss in der Lage sein, Text zu vergrößern und niemals Pixelartefakte zu sehen.
Kann jemand Vorschläge machen, wie ich vorgehen könnte?
Ich würde annehmen, dass Sie sich mit Methoden für vektorbasierte Schriftarten befassen müssen, anstatt mit gerasterten Schriftarten, die ein Ausgangspunkt sein könnten. Ich bin kein Experte in dieser Angelegenheit, also werde ich jemanden, der es wissen würde, antworten lassen.
Ray Dey
Antworten:
7
Es gibt drei gängige Möglichkeiten, dies zu tun. Es geht nicht wirklich darum, Artefakte vollständig zu eliminieren - was unmöglich ist, es sei denn, Sie haben unbegrenzten Speicher oder Prozessorzeit -, sondern darum, sie so zu minimieren, dass sie zu Ihrem vorhandenen Code und Ihren Zielplattformen passen.
Verwenden Sie zunächst einfach Ihren Schriftarten-Rasterizer - normalerweise FreeType -, um die Schrift beim Vergrößern auf die gewünschte Größe zu rasteren. Dies wird in Screenshots gut aussehen, ist aber unglaublich langsam. Sie können die Langsamkeit lösen, indem Sie Größen zwischenspeichern, aber dann wird es unglaublich speicherhungrig. In Bewegung sieht es auch nicht gut aus, da Glyphen für eine statische Anzeige gut aussehen müssen, wenn sie ungleichmäßig skaliert werden. Es ist jedoch eine Option, wenn Sie sich auf einer Plattform mit genügend Speicher befinden (wie einem PC) und Ihre Waage auf einen kleinen Bereich wie 10px bis 30px beschränkt ist. Diese Methode lässt auch nicht viel Augenweide für sich zu.
Zweitens können Sie Ihren Text als Netz speichern. Dazu gibt es einige Bibliotheken wie GLTT , oder Sie können Ihre eigenen schreiben. Jetzt haben Sie keine Pixelartefakte mehr, aber Sie haben polygonale Artefakte, wenn Sie ganz nah heran zoomen - genau wie jedes andere Netz in einem 3D-Spiel. Mesh-Text lässt eine Menge Augenweide zu, da Vertex-Shader angewendet werden können und das Mesh mit jeder anderen Weltzeichnung verschachtelt werden kann, die Sie machen. Der Speicher und die CPU sind relativ sparsam und die Kosten lassen sich leicht messen, da es sich nur um ein Standardnetz handelt. Die Integration in eine normale Sprite-basierte 2D-Rendering-Pipeline kann schwierig sein.
Drittens können Sie Entfernungsfelder in Kombination mit einem Pixel-Shader verwenden . Dies ist eine relativ neue Technik, die derzeit beliebt ist. Sie verwendet einen einfachen Shader, um eine vorgefertigte Textur abzutasten, und die "freie" bilineare Filterung auf Ihrer Grafikkarte, um Glyphen sauber zu skalieren. Im Vergleich zu anderen Methoden wird nur wenig und leicht vorhersehbarer Speicher benötigt - eine Textur von 0,5 MB bis 1 MB pro Zeichensatz pro Schriftart. Es passt gut in Sprite-basierte Rendering-Pipelines, da es Sprite-basiert ist. Jede Glyphe ist immer noch ein strukturiertes Quad. Es erzeugt zwar Pixelartefakte, aber nur sehr wenige im Vergleich zu anderen Methoden, die Texturen skalieren. Es gibt auch einen Fallback mit fester Funktion, wenn Pixel-Shader nicht verfügbar sind, der Text jedoch sehr voreingenommen ist. Da die Abtastung in einem Pixel-Shader erfolgt, werden einige Augenweiden wie Konturen und Schatten kostengünstig zugelassen.
Es gibt auch einen Forschungsartikel von Microsoft Research durch Schleifen und Blinn, auf der Erweisung auflösungsunabhängige Kurven mit Shadern. Es wird empfohlen, die vorgestellte Technik zu verwenden, um TrueType-Text auflösungsunabhängig zu rendern.
Sie müssen Ihre Schriftzeichen aus einer Kombination von Kurven und Linien erstellen, die Sie dann zur Laufzeit in Geometrie mit einem geeigneten Detaillierungsgrad konvertieren.
Glücklicherweise bestehen die meisten Schriftarten bereits aus Bezierkurven. Um die Kurvendaten abzurufen, müssen Sie sie nur mit der Standardfunktion Windows GetGlyphOutline () extrahieren.
Ich bin nicht sicher, ob Sie diese Kurvendaten von C # ohne PInvoke erhalten können.
Um diese plattformübergreifend zu gestalten und sich nicht um das PInvoke-Zeug zu kümmern, scheint es mir möglich zu sein, ein Tool zu schreiben, um die von GetGlyphOutline gelesenen Daten (siehe diese SO-Frage ) in ein benutzerdefiniertes Format zu übertragen und dann zu haben Einige einfache Datei-E / A im Spielcode, um nur Ihre benutzerdefinierten gespeicherten Glyphendaten zu laden.
Ricket
0
Vielleicht möchten Sie sich Freetype ansehen. Ich habe keine Ahnung, ob es auf Ihrer Plattform verfügbar ist oder ob die Lizenz anwendbar ist, aber es ist eine ziemlich ausgezeichnete Open-Source-Bibliothek zum Rendern von True-Type- und anderen Vektor-Schriftarten. Ich glaube, sie mussten einen cleveren Anwalt ausweichen, um Schriftarten auf ästhetisch ansprechende Weise wiederzugeben. Der wahre Typ besteht darin, Bytecodes in Kurven zu verwenden, um dem Renderer Hinweise zu geben, damit wichtige Schriftmerkmale (wie Vertikale und Serifen) nicht verschwimmen, wie dies bei einem naiven Standard-Anti-Aliasing der Fall wäre. Diese Technik ist patentiert, daher mussten sich die Freetype-Leute etwas anderes einfallen lassen, das den Job erledigte und sich nicht auf das schreckliche Anwaltstier von (glaube ich) Apple berief. Wie auch immer, abgesehen von der rechtlichen Programmierung, versuchen Sie, sich mit Freetype zu befassenhttp://freetype.sourceforge.net/index2.html
Antworten:
Es gibt drei gängige Möglichkeiten, dies zu tun. Es geht nicht wirklich darum, Artefakte vollständig zu eliminieren - was unmöglich ist, es sei denn, Sie haben unbegrenzten Speicher oder Prozessorzeit -, sondern darum, sie so zu minimieren, dass sie zu Ihrem vorhandenen Code und Ihren Zielplattformen passen.
Verwenden Sie zunächst einfach Ihren Schriftarten-Rasterizer - normalerweise FreeType -, um die Schrift beim Vergrößern auf die gewünschte Größe zu rasteren. Dies wird in Screenshots gut aussehen, ist aber unglaublich langsam. Sie können die Langsamkeit lösen, indem Sie Größen zwischenspeichern, aber dann wird es unglaublich speicherhungrig. In Bewegung sieht es auch nicht gut aus, da Glyphen für eine statische Anzeige gut aussehen müssen, wenn sie ungleichmäßig skaliert werden. Es ist jedoch eine Option, wenn Sie sich auf einer Plattform mit genügend Speicher befinden (wie einem PC) und Ihre Waage auf einen kleinen Bereich wie 10px bis 30px beschränkt ist. Diese Methode lässt auch nicht viel Augenweide für sich zu.
Zweitens können Sie Ihren Text als Netz speichern. Dazu gibt es einige Bibliotheken wie GLTT , oder Sie können Ihre eigenen schreiben. Jetzt haben Sie keine Pixelartefakte mehr, aber Sie haben polygonale Artefakte, wenn Sie ganz nah heran zoomen - genau wie jedes andere Netz in einem 3D-Spiel. Mesh-Text lässt eine Menge Augenweide zu, da Vertex-Shader angewendet werden können und das Mesh mit jeder anderen Weltzeichnung verschachtelt werden kann, die Sie machen. Der Speicher und die CPU sind relativ sparsam und die Kosten lassen sich leicht messen, da es sich nur um ein Standardnetz handelt. Die Integration in eine normale Sprite-basierte 2D-Rendering-Pipeline kann schwierig sein.
Drittens können Sie Entfernungsfelder in Kombination mit einem Pixel-Shader verwenden . Dies ist eine relativ neue Technik, die derzeit beliebt ist. Sie verwendet einen einfachen Shader, um eine vorgefertigte Textur abzutasten, und die "freie" bilineare Filterung auf Ihrer Grafikkarte, um Glyphen sauber zu skalieren. Im Vergleich zu anderen Methoden wird nur wenig und leicht vorhersehbarer Speicher benötigt - eine Textur von 0,5 MB bis 1 MB pro Zeichensatz pro Schriftart. Es passt gut in Sprite-basierte Rendering-Pipelines, da es Sprite-basiert ist. Jede Glyphe ist immer noch ein strukturiertes Quad. Es erzeugt zwar Pixelartefakte, aber nur sehr wenige im Vergleich zu anderen Methoden, die Texturen skalieren. Es gibt auch einen Fallback mit fester Funktion, wenn Pixel-Shader nicht verfügbar sind, der Text jedoch sehr voreingenommen ist. Da die Abtastung in einem Pixel-Shader erfolgt, werden einige Augenweiden wie Konturen und Schatten kostengünstig zugelassen.
quelle
Es gibt auch einen Forschungsartikel von Microsoft Research durch Schleifen und Blinn, auf der Erweisung auflösungsunabhängige Kurven mit Shadern. Es wird empfohlen, die vorgestellte Technik zu verwenden, um TrueType-Text auflösungsunabhängig zu rendern.
quelle
Sie müssen Ihre Schriftzeichen aus einer Kombination von Kurven und Linien erstellen, die Sie dann zur Laufzeit in Geometrie mit einem geeigneten Detaillierungsgrad konvertieren.
Glücklicherweise bestehen die meisten Schriftarten bereits aus Bezierkurven. Um die Kurvendaten abzurufen, müssen Sie sie nur mit der Standardfunktion Windows GetGlyphOutline () extrahieren.
Ich bin nicht sicher, ob Sie diese Kurvendaten von C # ohne PInvoke erhalten können.
quelle
Vielleicht möchten Sie sich Freetype ansehen. Ich habe keine Ahnung, ob es auf Ihrer Plattform verfügbar ist oder ob die Lizenz anwendbar ist, aber es ist eine ziemlich ausgezeichnete Open-Source-Bibliothek zum Rendern von True-Type- und anderen Vektor-Schriftarten. Ich glaube, sie mussten einen cleveren Anwalt ausweichen, um Schriftarten auf ästhetisch ansprechende Weise wiederzugeben. Der wahre Typ besteht darin, Bytecodes in Kurven zu verwenden, um dem Renderer Hinweise zu geben, damit wichtige Schriftmerkmale (wie Vertikale und Serifen) nicht verschwimmen, wie dies bei einem naiven Standard-Anti-Aliasing der Fall wäre. Diese Technik ist patentiert, daher mussten sich die Freetype-Leute etwas anderes einfallen lassen, das den Job erledigte und sich nicht auf das schreckliche Anwaltstier von (glaube ich) Apple berief. Wie auch immer, abgesehen von der rechtlichen Programmierung, versuchen Sie, sich mit Freetype zu befassenhttp://freetype.sourceforge.net/index2.html
quelle