Comment rendre les lignes de rendu de ligne plates?

10

J'ai remarqué que lorsque j'ajoute d'autres sommets à une ligne de rendu de ligne, la ligne se tord et cesse d'être une ligne lisse.

entrez la description de l'image ici

.GIF ici: http://i.imgur.com/hRAhCXM.gif

Toutes les lignes sont au même niveau z, même si j'enlève les matériaux, les lignes semblent toujours se tordre.

Je n'ai aucune idée pourquoi il fait cela, ou comment procéder pour le résoudre, des suggestions? C #

Douglas Gaskell
la source
C'est un problème avec l'algorithme utilisé par le LineRenderer pour positionner ses sommets, qui traite mal les angles vifs. Vous pouvez l'améliorer quelque peu en ajoutant plus de points pour arrondir les coins, mais la méthode la plus robuste que j'ai trouvée est de dupliquer sa fonctionnalité pour vous-même avec un meilleur algorithme, en créant un maillage dynamique avec les sommets dont vous avez besoin, ou de manière créative exploiter un ParticleSystem pour dessiner la chaîne de points.
DMGregory
1
Mise à jour: les versions ultérieures d'Unity (5 5+) ont amélioré l'algorithme LineRenderer , donc les utilisateurs qui envisagent d'utiliser LineRenderers peuvent trouver que le résultat prêt à l'emploi est nettement meilleur de nos jours.
DMGregory

Réponses:

11

Le problème est essentiellement le suivant:

entrez la description de l'image ici

Le LineRenderer essaie de connecter les positions des points rouges. Il crée les sommets verts pour faire un maillage. Ainsi, le segment de première ligne est superbe. Mais alors le LineRenderer essaie d'être économique, il réutilise les sommets de la fin d'un segment de ligne à la fin du deuxième segment de ligne. Quand il y a un angle aigu, vous obtenez le problème que vous voyez. Le deuxième segment de ligne est pincé à l'intersection car son «capuchon d'extrémité» n'est pas perpendiculaire à son autre «capuchon d'extrémité».

La solution est de créer votre propre rendu de ligne et de ne pas le rendre aussi économique. Vous pouvez le faire en générant un maillage dynamique . Le maillage sera composé d'une série de quadruples fins. Pour chaque segment de ligne, vous pouvez calculer les quatre coins du quad en calculant la normale de la ligne et une largeur de ligne spécifiée:

Vector3 normal = Vector3.Cross(start, end);
Vector3 side = Vector3.Cross(normal, end-start);
side.Normalize();
Vector3 a = start + side * (lineWidth / 2);
Vector3 b = start + side * (lineWidth / -2);
Vector3 c = end + side * (lineWidth / 2);
Vector3 d = end + side * (lineWidth / -2);

Ici, a, b, cet dconstituent les quatre coins d'un seul segment de ligne, tout comme les points verts dans l'image ci - dessus. Ces sommets seraient ajoutés au maillage, et vous ajouteriez également les indices pour transformer les quatre sommets en deux triangles (donc, six indices seraient ajoutés, abc et bdc).

Cela peut évidemment devenir assez complexe. Je crois qu'une autre raison pour laquelle Unity a implémenté leur LineRenderer comme ils l'ont fait est que le faire de cette façon évite un autre problème, les virages. Lorsque vous commencez à dessiner chaque segment de ligne, vous commencez à voir où les deux segments de ligne se rejoignent et forment une laideur. Il existe des moyens de résoudre ce problème en calculant la normale partagée entre les deux lignes et en mettant à jour leurs sommets vers la normale partagée, mais cela ne résout que partiellement le problème, car vous pouvez toujours vous retrouver facilement avec des lignes pincées. La solution la plus robuste consiste à générer des sommets supplémentaires au niveau des joints pour servir de coins.

MichaelHouse
la source
1
Vous pouvez également vous en sortir en utilisant le rendu de ligne d'unité et en insérant des points supplémentaires pour créer un petit onglet. Mettez simplement un point un peu vers le point suivant par rapport au point précédent.
mklingen
Grande explication Byte, merci. Je vais probablement essayer de voir si je ne peux pas générer plus de points à chacun des coins, si cela ne fonctionne pas bien, je vais essayer de faire un maillage dynamique. Je vous remercie.
Douglas Gaskell, le
1

J'ai eu le même problème et je le résous en ajoutant plus de points aux bords lisses ce n'est pas une solution élégante mais c'est simple et fonctionne. Au moins pour moi. J'ai écrit une fonction pour ce faire:

Vector3[] Generate_Points(Vector3[] keyPoints, int segments=100){
    Vector3[] Points = new Vector3[(keyPoints.Length - 1) * segments + keyPoints.Length];
    for(int i = 1; i < keyPoints.Length;i++){
        Points [(i - 1) * segments + i - 1] = new Vector3(keyPoints [i-1].x,keyPoints [i-1].y,0);
        for (int j = 1;j<=segments;j++){
            float x = keyPoints [i - 1].x;
            float y = keyPoints [i - 1].y;
            float z = 0;//keyPoints [i - 1].z;
            float dx = (keyPoints [i].x - keyPoints [i - 1].x)/segments;
            float dy = (keyPoints [i].y - keyPoints [i - 1].y)/segments;
            Points [(i - 1) * segments + j + i - 1] = new Vector3 (x+dx*j,y+dy*j,z);
        }
    }
    Points [(keyPoints.Length - 1) * segments + keyPoints.Length - 1] = new Vector3(keyPoints [keyPoints.Length-1].x,keyPoints [keyPoints.Length-1].y,0);
    return Points;
}
Miguel Ángel Llorente
la source
0

Une façon de résoudre ce problème pour les lignes opaques est de rendre un cercle à chaque joint. Le cercle doit avoir un diamètre égal à la largeur de la ligne. Cela nécessite quelques sommets supplémentaires pour être rendus, mais c'est vraiment sympa. Vous pouvez également vous débarrasser des normales partagées entre les articulations.

Cela nécessite toujours que vous écriviez votre propre code de rendu au lieu d'utiliser le rendu de ligne Unity.

J'ai créé un atout qui fait exactement cela sur http://u3d.as/nFE

jjxtra
la source
0

La façon dont j'ai évité cela est que je mets toujours la position z à 0 dans la méthode LineRenderer.SetPosition (). Donc au lieu d'écrire

LineRenderer.SetPosition(i, myVector3);

J'ai écrit

LineRenderer.SetPosition(i, new Vector3(myVector3.x, myVector3.y, 0));

Mais ce n'est pas la meilleure solution car vous obtiendrez toujours ces lignes étranges. La meilleure solution à laquelle je pouvais penser était de créer des lignes séparées. Cela a parfaitement fonctionné pour moi. J'espère que cela vous aidera.

Alexionder
la source