9
votes

Trempez lorsque vous rejoignez des lignes antialiasées mélangées

J'ai un problème lors de la jonction de deux lignes antialiasées lors de l'utilisation d'un mode de mélange, je reçois un plongeon au point où ils se joignent. En mélangeage, je veux dire que je dessine ma ligne antialiasée en calculant le rapport de la couleur de la couleur VS couleur VS, de sorte que lorsque le rapport pour un pixel est par exemple 70%, le nouveau pixel est de 0,7 * de couleur de ligne + 0,3 * Couleur de fond. Ma fonction d'antialiasing pour les lignes est essentiellement fabriquée à partir d'une fonction d'erreur (bien que je suppose que le même problème se pose pour la plupart des fonctions antialiasing), comme celui-ci:

0.5 + 0.5erf (-x)

Ainsi, lorsque deux lignes se rencontrent, on tire après l'autre, vous obtenez une trempette, l'articulation des deux lignes plonge jusqu'à 75% de l'intensité qu'elle devrait être à ce moment-là, à ce point, 50% de l'arrière-plan était conservé pour la La première ligne et puis 50% de ces 50% sont restées après la deuxième ligne lorsque 0% devraient être laissés:

1 - (-XERFC (-X) * 0.5ERFC (x))

Je ne peux que supposer que c'est un problème courant dans le dessin des graphiques raster antialiasés avec des lignes jointes, il doit donc avoir une solution commune, mais je n'ai aucune idée de ce que c'est. Merci!

aussi: juste pour être clair sur la manière dont les lignes sont dessinées, dans la largeur, les lignes sont fabriquées avec une fonction gaussienne (E ^ -x * x) et les deux extrémités sont arrondies à l'aide d'une erreur surélevée. les fonctions. Vous pouvez voir un exemple de quelle ligne horizontale longue de 10 px a l'air en entrant '0.5ERFC (-X-5) * 0.5ERFC (X-5) * E ^ (- Y * Y)' à Wolframalpha.


6 commentaires

La voie habituelle est d'avoir un algorithme pour dessiner des polylines afin que l'articulation entre les lignes ne soit pas tirée de la même manière qu'un point final.


Ok, alors comment un algorithme pour dessiner des polylignes est-il différent d'un algorithme unique? J'ai pensé avoir quelque chose comme une coupure aiguë pour aller d'une ligne à l'autre, le principal problème avec c'est que l'articulation serait angulaire qui n'est pas compatible avec ce que mon antialiasing gaussien devrait céder (le joint devrait être rond).


Désolé, je n'ai plus de détails ou j'aurais laissé une réponse au lieu d'un commentaire. Face au même problème il y a de nombreuses années, je suis juste allé avec suréchantillonnage et filtrage.


Les algorithmes de polyligne ont des règles spécifiques sur la manière de dessiner des articulations et des extrémités (vous avez souvent un choix de styles - par exemple, arrondi ou carré). Vous vous retrouvez efficacement avec une limite bien définie de quelque sorte - ce que votre antialiasing puisse briller.


Avez-vous regardé en alpha pré-composé, et celui-ci? Lukepalmer.wordpress.com/2010/02/05/associative-alpha -Blendi ng


Pourquoi ne faites-vous pas que le sommet de votre ERF s'étendit un peu plus loin. L'exemple que vous avez donné '0.5ERFC (-X-5) * 0.5ERFC (X-5) * E ^ (- Y * Y) doit être d'une ligne d'environ (-4,0) à (4,0) . Cela a plus de sens parce que vous contrôlez le centre de la brosse. Si vous voulez contrôler le bord de la brosse, le trempette que vous avez du sens.


4 Réponses :


1
votes

Faire de bonnes lignes continues composées de segments mélangés est en général n'allant pas être possible si vous les considérez comme des segments - si vous pensez simplement au cas d'une ligne, puis de dessiner le segment suivant soit au même angle puis à un angle de 90 degrés. les couleurs de pixels pour une ligne dépendent de l'angle qu'il rejoint avec la ligne suivante

Ce que vous devez alors penser est des segments avec des extrémités coudées.

Pour le dessiner, recherchez la littérature sur l'onglet de linejoin Bevel (onglet est probablement plus facile).


0 commentaires

0
votes

Si vous dessinez les lignes adjacentes avec le mélange, c'est un problème assez impossible.

Un bon moyen de penser à cela est une fonction de distance à une forme idéale. Une carte d'intensité de pixels (via une fonction) à distance de la forme. Avec deux lignes parfaites qui seraient tout simplement le minimum.

Malheureusement, cela signifie que vous avez besoin de la distance à chaque ligne qui pourrait influencer un pixel. C'est ce que font des rasterizes de texte.

Alternativement, vous ne manquez pas de lignes de poids. Ils sont sur ou éteints par pixel. Ensuite, vous laissez Super échantillonnage prendre soin du reste. C'est ce que les rendriers de vecteur logiciel comme Flash ou SVG DO.


0 commentaires

0
votes

L'idée de Thang peut être un bon point de départ: En bref pour contrôler le centre de la "brosse" à la place des bords. Idéalement avec de beaux points d'extrémité ronde, vous verriez de beaux coins rounds par cette approche.

La vérité ne sera toutefois pas aussi belle. Le problème est que vous avez d'abord alpha mélanger une ligne à votre surface cible, puis vous associez l'alpha mélange la deuxième ligne sur cette surface qui a déjà une ligne "brûlée". Le résultat final serait un blob plus gros dans le coin où deux pixels translucides sont blit les uns sur les autres (vous pouvez observer cet effet en réel si, par exemple, vous essayez de dessiner des segments de ligne de connexion dans GIMP).

Je pense que cela ne peut pas être travaillé à l'aide de cette approche simple à une ligne à la fois sur ce paramètre (vous auriez donc besoin d'aller dans la direction des autres réponses proposées, à l'aide d'algorithmes de polyline ou de super échantillonnage). Cependant, en fonction de vos objectifs, vous pouvez avoir une solution viable.

Ceci pré-rendu votre objet graphique à une surface séparée qui a alpha. Sur ce cas, vous pouvez combiner les alphas des lignes individuelles (telles que la prise du plus grand de pixels cible et du pixel tracé) qui vous donnera le résultat souhaité (pas de graisse des glaçons sur les coins).

L'inconvénient est que vous avez besoin d'une surface distincte que vous devez bliter sur votre cible lorsque l'objet est complet: cela nécessite une mémoire supplémentaire et une durée de traitement.

Vous pouvez contourner cela si vous avez juste besoin de rendre à une cible plate (couleur unique): alors vous n'avez tout simplement pas nécessairement besoin d'effectuer un mélange alpha approprié et peut faire la combinaison de calculs alpha en place. Cette solution peut être utilisable si l'arrière-plan est facilement calculé (tel qu'une grille de coordonnée), donc dans l'ensemble dans l'ensemble, lorsque vous pouvez facilement obtenir la valeur de pixel d'origine de l'arrière-plan et que vous êtes en mesure de combiner contre cela (véritablement cela fonctionnera également. Si vous gardez l'arrière-plan sur lequel vous rendant dans une surface séparée, mais encore une fois, vous avez une autre surface dans la mémoire, donc probablement rien gagné).

Si votre problème est d'une autre nature, il peut également être fonctionnel si vous conservez ces surfaces séparées rendantes, c'est essentiellement que vous préparez vos objets de lignes, puis ne les utilisez plus que comme textures ou tuiles.


0 commentaires

0
votes

Finalement, j'ai trouvé la réponse à ce problème. Il n'y a pas de moyen raisonnable de le faire en dessinant directement une ligne après l'autre directement sur l'image principale, car vous ne voulez pas que les lignes soient mélangées ensemble, vous voulez qu'ils soient ajoutés ensemble puis à la suite de cette somme des lignes. mélangé dans l'image principale.

Cependant, c'est difficile à manier si vous devez dessiner toutes ces lignes vers un tampon séparé puis mélanger le tampon entier sur le tampon principal, ce que j'ai envisagé et rejeté comme inapproprié avant de poser cette question. Heureusement depuis lors, j'ai totalement changé mon approche, au lieu d'avoir un tampon sur lequel dessiner l'élément après élément, j'utilise une approche par pixelle où chaque pixel est calculé directement en passant par une liste d'éléments à dessiner, pour le sakir de parallélisation (avec opencl). Donc, au lieu de devoir utiliser des tampons supplémentaires, j'ai simplement besoin d'un petit tableau pouvant contenir quelques valeurs de pixels supplémentaires et dans ma liste d'éléments à dessiner, j'ai des éléments qui servent de crochets, donc par exemple au lieu d'avoir:

image => (Mélange) Line1 => (Mélange) Line2 => (Mélange) Line3

Je peux avoir:

image => (Mélange) [0 => (Ajouter) Line1 => (Ajouter) Line2 => (Ajouter) Ligne3]

Qui est fait en remplaçant l'utilisation d'une valeur de pixels unique en ayant une gamme de valeurs pour chaque niveau de profondeur de crochets, donc dans ce cas à V [0] vous auriez le pixel de image , alors vous commenceriez par V [1] à 0 et ajoutez chaque ligne à elle et lorsque toutes les lignes sont ajoutées, la fermeture du support ferait la fermeture de la corcive Code> V [1] être mélangé dans V [0] et la valeur de pixel résultante correcte serait là.

Alors c'est tout, c'est assez simple, ce n'est qu'un problème si vous ne vous permettez pas d'utiliser l'équivalent d'un groupe de couches dans Photoshop.


0 commentaires