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:
int main() {
// Bilinear sampling of the distance field
vec3 s = texture2D(sdf, p).rgb;
// Acquire the signed distance
float d = median(s.r, s.g, s.b) - 0.5;
// Weight between inside and outside (anti-aliasing)
float w = clamp(d/fwidth(d) + 0.5, 0.0, 1.0);
// Combining the background and foreground color
gl_FragColor = mix(outsideColor, insideColor, w);
}
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.