203 votes

Quel est l'état de l'art pour le rendu de texte dans OpenGL à partir de la version 4.1?

Il y a déjà un certain nombre de questions sur le texte rendu en OpenGL, tels que:

Mais surtout, ce qui est discuté est rendu texturé quads à l'aide de la fonction fixe pipeline. Sûrement shaders doit faire une meilleure façon.

Je ne suis pas vraiment préoccupé par l'internationalisation, la plupart de mes chaînes seront parcelle étiquettes de graduation (date et l'heure ou purement numérique). Mais le parcelles seront à nouveau rendu à l'écran le taux de rafraîchissement et il pourrait être tout à fait un peu de texte (pas plus de quelques milliers de glyphes à l'écran, mais suffisamment que pour l'accélération matérielle présentation serait sympa).

Qu'est-ce que l'approche recommandée pour le texte-rendu en utilisant OpenGL moderne? (En citant les logiciels existants à l'aide de l'approche est la preuve qu'il fonctionne bien)

  • Geometry shaders qui acceptent par exemple de la position et de l'orientation et une séquence de caractères et émettent de la texture quads
  • Geometry shaders que le rendu des polices vectorielles
  • Comme ci-dessus, mais en utilisant un pavage de shaders à la place
  • Un compute shader pour faire la police de la pixellisation

208voto

Damon Points 26437

Le rendu des contours, à moins que le rendu d'une douzaine de caractères au total, reste un "no go" en raison du nombre de sommets par caractère approximatif de la courbure. Bien qu'il y ait eu des approches pour évaluer les courbes de bézier dans le pixel shader au lieu de cela, ces souffrent de n'être pas facilement lissé, ce qui est trivial à l'aide d'une distance-carte de texture quad, et l'évaluation des courbes dans le shader est encore computionally beaucoup plus cher que nécessaire.

Le meilleur compromis entre "rapide" et de la "qualité" sont toujours texturé quads signé à distance du champ de la texture. Il est très légèrement plus lent que d'utiliser une plaine normal texturé quad, mais pas tellement. La qualité d'autre part, est dans un tout autre ordre de grandeur. Les résultats sont vraiment magnifique, il est aussi rapide que vous pouvez obtenir, et des effets tels que la lueur sont trivialement facile à ajouter, trop. Aussi, la technique peut être déclassé bien pour du matériel plus ancien, si nécessaire.

Voir le célèbre Valve de papier pour la technique.

La technique est conceptuellement similaire à la façon dont surfaces implicites (metaballs et par exemple), même si elle ne génère pas de polygones. Il fonctionne entièrement dans le pixel shader et prend de la distance échantillonnés à partir de la texture en fonction de distance. Tout au-dessus d'un seuil choisi (généralement 0,5) est "in", tout le reste est "out". Dans le cas le plus simple, sur 10 ans non-shader-capable de matériel, réglage de l'alpha test de seuil à 0,5 va faire exactement la même chose (mais sans les effets spéciaux et l'antialiasing).
Si on veut ajouter un peu plus de poids à la police (faux gras), un peu moins de seuil fera l'affaire sans modifier une seule ligne de code (il suffit de changer votre "font_weight" uniforme). Pour un effet de brillance, tout simplement, on les considère au-dessus d'un seuil "dans" et tout au-dessus de l'autre (la plus petite), seuil ", mais en éclat", et de LERPs entre les deux. L'anticrénelage fonctionne de la même façon.

À l'aide d'un 8-bit signé de la valeur de distance plutôt que d'un seul bit, cette technique augmente la résolution efficace de votre texture de 16 fois dans chaque dimension (au lieu du noir et blanc, toutes les nuances sont utilisés, nous avons donc 256 fois les informations en utilisant le même stockage). Mais même si vous agrandissez bien au-delà de 16x, le résultat semble tout à fait acceptable. Les longues lignes droites finira par devenir un peu ondulée, mais il n'y aura pas de profil type "polyédrique" les artefacts de prélèvement.

Vous pouvez utiliser un geometry shader pour générer les quads de points (réduire la bande passante du bus), mais honnêtement, les gains sont plutôt marginales. Le même est vrai pour instanciées caractère de rendu comme décrit dans GPG8. La surcharge de l'instanciation n'est amorti si vous avez beaucoup de texte à dessiner. Les gains sont, à mon avis, en aucun rapport avec la complexité et la non-downgradeability. De Plus, vous êtes limité par le montant de la constante de registres, ou vous devez lire à partir d'une texture de la mémoire tampon de l'objet, qui n'est pas optimale pour la cohérence de cache (et le but était d'optimiser, pour commencer!).
Un simple, un bon vieux vertex buffer est tout aussi rapide (peut-être plus rapidement) si vous planifiez le téléchargement un peu en avance dans le temps et qui va s'exécuter sur tous les matériels construits au cours des 15 dernières années. Et, il n'est pas limité à un nombre de caractères dans la police, ni à un nombre de caractères à afficher.

Si vous êtes sûr que vous n'avez pas plus de 256 caractères dans votre police, de la texture des tableaux peut être la peine d'un examen à la bande la bande passante du bus dans une manière semblable à la génération des quads à partir de points dans le geometry shader. Lors de l'utilisation d'un tableau de texture, les coordonnées de texture de tous les quads sont identiques, constant s et t coordonnées et ne diffèrent que dans l' r coordonner, ce qui est égal au caractère d'indice de rendu.
Mais comme avec les autres techniques, les gains attendus sont marginale et le coût d'être incompatible avec la précédente génération de matériel.

Il est un outil pratique par Jonathan Dummer pour la génération de distance de textures: la page de description

Mise à jour:
Comme l'a récemment souligné dans Programmables Sommet de Traction (D. Rákos, "OpenGL Insights", pp. 239) n'est pas significative latence supplémentaire ou des frais généraux associés à la traction sommet de données par programmation à partir de l'ombrage sur les dernières générations de Gpu, par rapport à faire de même en utilisant le standard de fonction fixe.
Aussi, les dernières générations de Processeurs de plus en plus, de taille raisonnable, à des fins générales caches L2 (par exemple 1536kiB sur nvidia Kepler), donc on peut s'attendre de la incohérente problème d'accès lors de l'extraction aléatoire de compensations pour le quad coins à partir d'un tampon texture être moins un problème.

Cela rend l'idée de traction constante des données (telles que quad tailles) à partir d'un tampon texture plus attrayant. Une hypothétique mise en œuvre pourrait, ainsi, de réduire PCIe et la mémoire des transferts, ainsi que la mémoire GPU, au minimum avec une approche comme ceci:

  • Seulement de téléchargement d'un caractère d'index (un par personnage à être affiché) comme la seule entrée d'un vertex shader qui passe sur cet indice et gl_VertexID, et d'amplifier que de 4 points dans le géométrie shader, de toujours avoir le caractère d'index et que le sommet de l'id (ce sera "gl_primitiveID mis à disposition dans le vertex shader") comme le seul attributs, et la capture via la transformation de la rétroaction.
  • Ce sera rapide, car il ya seulement deux attributs de sortie (principal goulot d'étranglement en GS), et il est proche de "non-op", sinon dans les deux étapes.
  • Lier un tampon texture qui contient, pour chaque caractère dans la police, la texture de la quad positions des sommets par rapport au point de base (ce sont essentiellement les "mesures de police"). Ces données peuvent être compressées à 4 numéros par quad en ne stockant que le décalage de la partie inférieure gauche du vertex, et de codage de la largeur et de la hauteur de l'axe aligné boîte (en supposant que la moitié des flotteurs, ce sera de 8 octets de constante tampon par caractère, typique des 256 caractères de la police pourrait s'insérer complètement dans 2kiB du cache L1).
  • Définir un uniforme pour la ligne de base
  • Lier un tampon de la texture avec des décalages horizontaux. Ces pourrait probablement même être calculé sur le GPU, mais il est beaucoup plus facile et plus efficace pour ce genre de chose sur le CPU, car il est strictement séquentielle et n'est pas du tout trivial (crénage). Aussi, il aurait besoin d'un autre feedback passer, ce qui serait un autre point de synchronisation.
  • Rendu précédemment, les données générées à partir de la rétroaction de la mémoire tampon, le vertex shader tire le décalage horizontal du point de base et les décalages de l'angle des sommets de tampon d'objets (à l'aide de la primitive id et le caractère d'index). L'original ID sommet des sommets est maintenant notre "primitive ID" (rappelez-vous la GS tourné les sommets en quads).

Comme cela, on pourrait, idéalement, de réduire le sommet de la bande passante par 75% (après amortissement), mais il ne serait en mesure de rendre une seule ligne. Si on voulait être en mesure de rendre plusieurs lignes dans un appel, il faut ajouter la ligne de base de la mémoire tampon texture, plutôt que d'utiliser un uniforme (ce qui rend la bande passante des gains plus petits).

Toutefois, même en supposant une réduction de 75% - depuis le sommet de données à afficher "raisonnable" d'un montant de texte n'est qu'à quelque part autour de 50-100kiB (qui est pratiquement de zéro à un GPU ou un bus PCIe) -- j'ai toujours le doute que l'augmentation de la complexité et de perdre la compatibilité ascendante est vraiment la peine. La réduction à zéro par 75% est toujours nulle. J'ai certes pas essayé l'approche ci-dessus, et plus de recherche serait nécessaire pour en faire une véritable déclaration qualifiée. Mais encore, sauf si quelqu'un peut prouver que vraiment impressionnante différence de performances (utilisation "normale" d'un montant de texte, pas des milliards de caractères!), de mon point de vue reste que, pour le sommet de données, un simple, à la vieille vertex buffer est à juste titre assez bon pour être considéré comme faisant partie d'un "état de l'art solution". C'est simple, il fonctionne, et il fonctionne bien.

Ayant déjà référencé "OpenGL " Perspectives" ci-dessus, il vaut la peine de signaler également le chapitre "Forme 2D Rendu par la Distance des Champs" par Stefan Gustavson, ce qui explique la distance de terrain, le rendu dans le plus grand détail.

15voto

Display Name Points 495

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

La principale différence entre GLyphy et d'autres SDF basé sur OpenGL renderer est que la plupart des autres projets de l'échantillon de la SDF dans une texture. Cela a pour tous les problèmes habituels d'échantillonnage. C'est à dire. elle déforme le contour et est de faible qualité. GLyphy représente au contraire le SDF à l'aide de vecteurs réels soumis à la GPU. Il en résulte de très haute qualité de rendu.

L'inconvénient est que le code est pour iOS avec OpenGL ES. Je vais probablement faire un Windows/Linux OpenGL 4.x port (j'espère que l'auteur va ajouter un peu de documentation réelle, tout de même).

14voto

datenwolf Points 85093

La plus répandue consiste encore texturés quads. Cependant en 2005 LORIA développé quelque chose appelé vecteur textures, c'est-à-dire rendu vectoriel comme textures sur les primitives. Si on utilise ceci pour convertir les polices TrueType ou OpenType dans une texture vecteur vous obtenez ceci :

http://Alice.Loria.fr/index.php/publications.html?Paper=VTM@2005

9voto

user3588161 Points 305

Je suis surpris de Marque Kilgard du bébé, NV_path_rendering (NVpr), n'a pas été mentionné par tout ce qui précède. Bien que ses objectifs sont plus générales que le rendu des polices, il peut aussi rendre le texte à partir de polices et avec le crénage. Il ne nécessite même pas d'OpenGL 4.1, mais c'est un vendeur/Nvidia-extension uniquement pour le moment. Il s'avère essentiel de polices dans des chemins à l'aide de glPathGlyphsNV qui dépend de la freetype2 bibliothèque pour obtenir les paramètres de mesure, etc. Ensuite, vous pouvez également accéder à la crénage info avec glGetPathSpacingNV et l'utilisation NVpr général de chemin de rendu mécanisme pour afficher le texte d'aide du chemin d'accès-"converti" polices. (Je l'ai mis entre guillemets, car il n'y a pas de véritable conversion, les courbes sont utilisées comme est.)

Le enregistré une démo NVpr de capacités de police est malheureusement pas particulièrement impressionnant. (Peut-être que quelqu'un devrait faire un le long des lignes de la beaucoup snazzier SDF démo on peut trouver sur les intertubes...)

L'2011 NVpr API discours de présentation pour les polices partie commence ici et se poursuit dans la partie suivante; c'est un peu malheureux comment cette présentation est divisée.

Plus de matières générales sur NVpr:

  • Nvidia NVpr hub, mais certaines matières sur la page de destination n'est pas le plus up-to-date
  • Siggraph 2012 papier pour le cerveau du chemin-rendu de méthode, appelée "pochoir, puis couvrir" (StC); il décrit aussi brièvement que la concurrence tech comme Direct2D œuvres. Les polices de caractères bits ont été reléguées à une annexe de la feuille de papier. Il y a aussi quelques extras comme les vidéos/démos.
  • GTC 2014 présentation d'un état de mise à jour; en un mot: c'est désormais pris en charge par Google Skia (Nvidia fourni le code à la fin de 2013 et 2014), qui à son tour est utilisé dans Google Chrome et [indépendamment de Skia, je pense que] dans une version bêta d'Adobe Illustrator CC 2014
  • la documentation officielle de l'extension OpenGL registre
  • L'USPTO a accordé au moins quatre brevets pour Kilgard/Nvidia en relation avec NVpr, dont vous devriez être au courant, dans le cas où vous souhaitez mettre en œuvre StC par vous-même: US8698837, US8698808, US8704830 et US8730253. Notez qu'il existe quelque chose comme 17 de plus USPTO documents liés à cette "également publié en tant que", dont la plupart sont des demandes de brevet, de sorte qu'il est tout à fait possible plus des brevets peuvent être délivrés à partir de ceux-ci.

Et puisque le mot "pochoir" n'a pas produit tous les hits sur cette page avant ma réponse, il semble que le sous-ensemble de la communauté qui ont participé sur cette page, dans la mesure où, en dépit d'être assez nombreux, ignorante de pavage-gratuit, le stencil-buffer-basées sur des méthodes de chemin/de rendu des polices en général. Kilgard a une FAQ-comme post sur l'opengl forum qui peut éclairer la façon dont le pavage de libre parcours rendu méthodes diffèrent de la tourbière de la norme graphismes en 3D, même s'ils sont toujours à l'aide d'un [GP]GPU. (NVpr besoin d'un CUDA compatible puce.)

Pour une perspective historique, Kilgard est également l'auteur du classique "d'Un Simple basé sur OpenGL API pour la Texture plaquée Texte", SGI, 1997, ce qui ne doit pas être confondu avec le pochoir à base de NVpr qui a débuté en 2011.


La plupart, si pas toutes les méthodes récentes qui sont présentés sur cette page, y compris le pochoir à base de méthodes comme NVpr ou SDF basée sur des méthodes comme GLyphy (dont je ne suis pas en train de parler ici car d'autres réponses déjà le couvrir) ont cependant une limite: ils sont adaptés pour le grand affichage d'un texte sur les classiques (~100 DPI) moniteurs sans jaggies à n'importe quel niveau de l'échelle, et ils ont aussi agréable à regarder, même de petite taille, à haute résolution, de la rétine, comme s'affiche. Ils ne sont pas d'assurer pleinement ce que Microsoft Direct2D+DirectWrite vous donne cependant, à savoir l'affinage de petites glyphes sur les écrans. (Pour un examen visuel de la consigne en général voir ce typotheque page par exemple. Un plus en profondeur de la ressource est sur antigrain.com.)

Je ne suis pas au courant de tout ouvrir et productized basé sur OpenGL trucs qui peuvent faire ce que Microsoft peut avec allusion à l'instant. (Je dois admettre à l'ignorance de la part d'Apple OS X GL/Quartz interne, parce que, au meilleur de ma connaissance, Apple n'a pas publié la façon dont ils le font GL-fondé de la police/chemin de rendu des trucs. Il semble que OS X, à la différence de MacOS 9, ne fait pas allusion à tous, ce qui agace certaines personnes.) De toute façon, il y a un 2013 document de recherche qui traite de l'affinage via OpenGL shaders écrit par l'INRIA Nicolas P. Rougier; c'est probablement la peine de lire si vous devez faire allusion à partir d'OpenGL. Même s'il peut sembler qu'une bibliothèque comme freetype déjà fait tout le travail quand il s'agit de cela, ce n'est pas réellement si pour la raison suivante, je cite à partir de l'étude:

La bibliothèque FreeType pouvez pixelliser un glyphe à l'aide de sous-pixel de l'anti-aliasing dans le mode RVB. Cependant, ce n'est que la moitié du problème, car nous voulons aussi réaliser des sous-pixels positionnement pour le placement précis des glyphes. L'affichage de la texture de quad à les fractions les coordonnées des pixels ne résout pas le problème, puisque seuls les résultats dans la texture l'interpolation à l'ensemble de niveau du pixel. Au lieu de cela, nous voulons atteindre un précis de la maj (entre 0 et 1) dans le sous-domaine. Cela peut être fait dans un fragment shader [...].

La solution n'est pas exactement trivial, donc je ne vais pas essayer de l'expliquer ici. (Le document est en libre accès.)


Une autre chose que j'ai appris de Rougier de papier (et qui Kilgard ne semble pas avoir pris en compte), c'est que la police de pouvoirs (Microsoft+Adobe) ont créé non pas un mais deux de crénage spécification des méthodes. Le vieux est basé sur une soi-disant kern table et il est pris en charge par freetype. La nouvelle est appelée objets de stratégie de groupe et c'est uniquement pris en charge par de nouvelles bibliothèques de polices comme HarfBuzz ou pango dans le monde du logiciel libre. Depuis NVpr ne semble pas à l'appui de ces bibliothèques, le crénage peut ne pas fonctionner hors de la boîte avec NVpr pour certains de nouvelles polices de caractères; il y a certains de ceux qui, apparemment, dans la nature, selon ce forum de discussion.

Enfin, si vous avez besoin de faire un texte complexe (CTL) vous semblent être hors de la chance avec OpenGL comme pas basé sur OpenGL bibliothèque semble exister pour que. (DirectWrite sur l'autre main peut gérer CTL.) Il y a open-source des bibliothèques comme HarfBuzz qui peut rendre CTL, mais je ne sais pas comment vous pouvez les faire fonctionner (en utilisant le pochoir à base de méthodes) via OpenGL. Vous auriez probablement à écrire le code de la colle à l'extrait de la ré-forme des contours et de les introduire dans NVpr ou SDF les solutions reposant sur les chemins.

3voto

Orhun Points 178

Je pense que le mieux serait de chercher en graphiques cairo avec OpenGL backend.

Le seul problème que j’ai eu quand le développement d’un prototype avec le noyau 3.3 a été désapprouvée utilisation fonction dans OpenGL backend. Il y a 1-2 ans alors situation pourrait avoir amélioré...

En tout cas, j’espère à l’avenir des pilotes graphiques opengl Bureau mettra en œuvre OpenVG.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X