Les champs de distance signés (SDF) ont été présentés comme une solution rapide permettant à Valve d’obtenir un rendu des polices indépendant de la résolution dans cet article .
La solution Valve fonctionne déjà, mais j'aimerais préserver la netteté dans les coins. Valve indique que sa méthode peut obtenir des angles vifs en utilisant un deuxième canal de texture AND avec celui de base, mais ne permet pas d'expliquer comment ce deuxième canal serait généré.
En fait, il y a beaucoup de détails de mise en œuvre laissés en dehors de ce document.
J'aimerais savoir si l'un de vous pourrait m'indiquer la direction à suivre pour obtenir le rendu des polices SDF avec des angles vifs.
texture
signed-distance-field
font-rendering
Felipe Lira
la source
la source
Réponses:
Adam Simmons a fait un travail intéressant dans ce domaine. Je ne sais pas exactement comment il y est parvenu, mais son rendu vectoriel basé sur SDF est le plus net que j'ai jamais vu dans la pratique en dehors de Valve. http://twitter.com/adamjsimmons/status/611677036545863680
la source
EDIT: S'il vous plaît voir mon autre réponse avec une solution concrète.
En fait, j'ai résolu ce problème il y a un an dans le cadre de ma thèse de maîtrise. Dans le document Valve, ils montrent que vous pouvez ET deux champs de distance pour y parvenir, ce qui fonctionne tant que vous n’avez qu’un seul angle convexe. Pour les angles concaves, vous avez également besoin de l'opération OR. Ce gars a en fait développé un système obscur pour basculer entre les deux opérations en utilisant quatre canaux de texture.
Cependant, il existe une opération beaucoup plus simple qui peut faciliter les opérations ET et OU en fonction de la situation, et telle est l’idée principale de ma thèse: la médiane de trois . Donc, en gros, vous utilisez exactement trois canaux (idéaux pour RGB), qui sont complètement interchangeables, et vous les combinez à l’aide de l’opération médiane (choisissez la valeur moyenne parmi les trois).
Pour prendre en charge l'anti-aliasing, nous ne travaillons pas uniquement avec des booléens, mais avec des valeurs à virgule flottante. L'opération AND devient le minimum et l'OU devient le maximum de deux valeurs. La médiane de trois peut en effet faire les deux: si a < b , pour ( a , a , b ), la médiane est le minimum, et pour ( a , b , b ), il est le maximum.
Le processus de rendu est encore extrêmement simple. Le fragment shader entier, y compris l'anti-aliasing, peut ressembler à ceci:
La seule différence par rapport à la méthode originale est donc de calculer la médiane juste après l'échantillonnage de la texture. Vous devrez cependant implémenter la fonction médiane, ce qui peut être fait avec seulement 4 opérations min / max. .
Maintenant, bien sûr, la question est, savoir comment créer un tel champ de distance à trois canaux.Et c'est la partie la plus délicate. L’approche la plus évidente que j’ai adoptée au début consistait à décomposer la forme / le glyphe d’entrée en trois composantes, puis à générer un champ de distance conventionnel à partir de chacune d’elles. Les règles pour cette décomposition ne sont pas si compliquées. Premièrement, la zone avec au moins 2 canaux sur 3 est l’intérieur. Ensuite, si vous imaginez qu'il s'agit des canaux de couleur RVB, les coins convexes doivent être constitués d'une couleur secondaire et ses deux composants principaux doivent continuer vers l'extérieur. Les coins concaves sont l'inverse: deux couleurs secondaires entourent leur couleur primaire commune et le coin entre les deux bords qui restent à l'intérieur est blanc. J’ai également constaté qu’un certain rembourrage était nécessaire là où deux couleurs primaires ou deux couleurs secondaires se toucheraient sinon pour éviter les artefacts (par exemple, dans le trait du milieu du "N").
L'image suivante est un exemple de décomposition générée par le programme à partir de ma thèse:
Cette approche présente toutefois certains inconvénients. L'un d'eux est que les effets spéciaux, tels que les contours et les ombres, ne fonctionneront plus correctement. Heureusement, j'ai aussi mis au point une seconde méthode, beaucoup plus élégante, qui génère directement les champs de distance et prend même en charge tous les effets graphiques. Il est également inclus dans ma thèse et a donc également plus d'un an. Je ne vais pas donner plus de détails pour le moment, car je suis en train d’écrire un article décrivant cette seconde technique en détail, mais je le posterai ici dès que ce sera terminé.
Quoi qu'il en soit, voici un exemple de la différence de qualité. La résolution de la texture est la même dans chaque image, mais celle de gauche utilise une texture régulière, celle du milieu utilise un champ de distance ordinaire et celle de droite utilise mon champ de distance de trois canaux. Le surcoût lié aux performances n’est que la différence entre l’échantillonnage d’une texture RVB et d’une texture monochrome.
la source
Désolé de cette longue attente, mais il est devenu évident que bien que l’article que j’ai promis soit en principe complet, le processus de publication prendra un certain temps. Par conséquent, j'ai plutôt préparé un programme open source avec mon nouvel algorithme de construction de champs de distance multicanaux, msdfgen , que vous pouvez essayer dès maintenant.
Il est disponible sur GitHub: https://github.com/Chlumsky/msdfgen
(Je suis nouveau dans ce domaine, alors faites-le-moi savoir s'il y a un problème avec le référentiel.)
Quelqu'un a également demandé comment il se compare à un champ de distance monochrome plus important. Voici donc un aperçu de la différence de qualité. Cependant, cela dépend vraiment de la police de caractères, et je ne dirais pas que cela vaut toujours les données supplémentaires.
la source
Plutôt interessant! Je suis l'auteur du journal sur la distance signé par valve. Désolé que les détails de la mise en œuvre soient un peu clairsemés. J'ai seulement inclus l'exemple des deux canaux en tant que travail futur - je n'avais pas de générateur. Je pensais que quelque chose comme générer un sdf haute résolution puis une segmentation basée sur l'angle de la pente du sdf serait une tactique raisonnable. Mais je n'y suis jamais arrivé. Tous les schémas multicanaux doivent être comparés à l’utilisation de données monocanal de résolution supérieure du même empreinte mémoire, pour les ratios de grossissement requis par votre application.
la source
Je ne suis nullement un expert en la matière, mais vous pourriez peut-être, du moins en théorie, conserver des angles vifs dans un pseudo-SDF monochromatique si vous utilisiez soit un filtre bilatéral, soit un filtre directionnel bicubique au lieu d'un filtre bilinéaire standard. Outre l'avantage évident d'économiser de la mémoire, vous pouvez également disposer de plusieurs canaux pour les décalcomanies SDF multicolores.
Alternativement, si cela ne vous dérange pas d’utiliser un second canal, vous pouvez également essayer d’avoir un canal pour Distance horizontale et un autre pour Distance verticale, et utiliser une pyramide d’énergie Différence de Laplacien (DoL) pour compresser la texture de manière à éviter les informations redondantes. ne pas être enregistré.
Une troisième et dernière solution théorique consisterait à expérimenter une texture échantillonnée de manière hexagonale via l’adressage d’ensembles de tableaux.
Malheureusement, je n'ai actuellement aucun moyen de tester mes idées et n'ai trouvé aucun document décrivant ou testant quelque chose de similaire à mes idées. Je vais relier tous les articles pertinents où j'ai eu mon information / idées sous peu.
la source