web-dev-qa-db-fra.com

Est-ce vraiment si difficile de tracer des lignes lisses dans Unity?

Cela faisait un moment que j'essayais de tracer des lignes lisses dans Unity, mais avec Line Renderer, je n'obtenais que des lignes irrégulières aux angles non arrondis, en particulier lorsque l'angle de courbure est très petit. J'ai augmenté la valeur de l'antialiasing dans les réglages de qualité et essayé différents matériaux, mais rien n'a changé. J'ai aussi essayé d'instancier une sphère à chaque fois que la souris bouge, mais cela crée des écarts entre les différentes sphères, en particulier lorsque la souris va vite. Je sais qu'il existe un plugin appelé Vectrosity pour cela, mais il existe un moyen de réaliser cela sans cela?

9
rickyxd

Je n’ai obtenu que des lignes déchiquetées aux angles non arrondis, en particulièrement lorsque l’angle de courbure est vraiment petit.

C'était un problème dans Unity 5.4 et inférieur. Ce problème a été corrigé dans Unity 5.5 et version ultérieure après que LineRenderer a été complètement repensé.

Tout ce que vous avez à faire est de mettre à jour Unity 5.5 ou la version ci-dessus et ce problème devrait disparaître.

Il existe une nouvelle variable appelée LineRenderer.numCornerVertices. Vous pouvez l'utiliser pour définir le degré de fluidité de la ligne. La valeur de 5 semble bien pour cela.

Il existe également une autre nouvelle variable appelée LineRenderer.numCapVertices qui peut être utilisée pour définir le niveau de lissage de end de la ligne.

Voici une capture d’écran montrant les modifications apportées entre 5.4 et 5.5:

 enter image description here

8
Programmer

Vous pouvez obtenir de bons résultats en générant un maillage à partir d'un ensemble de points.

L'algorithme utilisé est le suivant:

  1. Vous avez un ensemble de points, qui pourraient être générés avec la courbe de Bézier.

 enter image description here

  1. Pour chaque point, prenez un vecteur directionnel au point suivant v = (p2 - p1)(en bleu). Ensuite, faites pivoter ce vecteur de 90 degrés normal = v.y, -v.xmarqué en rouge.

 enter image description here

  1. Cela montre que nous allons utiliser chaque normale à partir de la position du point. Vous pouvez maintenant multiplier ce vecteur dans les deux sens par la largeur souhaitée de la ligne.

 enter image description here

  1. Créez les sommets à ces positions.

 enter image description here

  1. Ajoutez des index pour former des triangles. Ce sera quelque chose comme [i, w/2 + i, w/2 + i + 1]i est l'index actuel et w est le nombre total de sommets.

 enter image description here

  1. Créez les autres triangles. Encore quelque chose comme [i, w/2 * i + 1, i + 1]

 enter image description here

  1. Et le résultat final. Vous pouvez ajouter plus de points pour rendre la ligne plus lisse.

 enter image description here

21
Iggy

Grâce à l'inspiration de @Iggy et aux tutoriels sur catlikecoding.com (d'où provient le code de la spline que j'utilise), j'ai créé un composant qui créera un maillage basé sur une spline avec une largeur et une fréquence d'échantillonnage. Fréquence d'échantillonnage plus élevée = courbe plus lisse bien sûr.

using UnityEngine;

[ExecuteInEditMode]
[RequireComponent(typeof(MeshFilter), typeof(MeshRenderer), typeof(BezierSpline))]
public class SplineMesh : MonoBehaviour {

  [Range(1, 20)]
  public int sampleFrequency = 5;

  [Range(0, 5f)]
  public float lineWidth = 0.3f;

  BezierSpline spline;
  Mesh mesh;

  private void Awake () {
    spline = GetComponent<BezierSpline>();
    mesh = GetComponent<Mesh>();
  }

  void Update()
  {
    /*
    for(int i = 0; i <= sampleFrequency; i++){
      float interval = i / (float)sampleFrequency;

      var point = spline.GetPoint(interval);
      var direction = spline.GetDirection(interval);

      var perpendicularLeftVec = PerpendicularLeft(direction) * lineWidth;
      var perpendicularRightVec = PerpendicularRight(direction) * lineWidth;

      Debug.DrawLine(point, point + (Vector3)perpendicularLeftVec, Color.Magenta, 0.5f, false);
      Debug.DrawLine(point, point + (Vector3)perpendicularRightVec, Color.cyan, 0.5f, false);
    }
    */
  }

    Vector2 PerpendicularRight(Vector2 orig){
        var vec = new Vector2(orig.y, -orig.x);
        vec.Normalize();
        return vec;
    }
    Vector2 PerpendicularLeft(Vector2 orig){
        var vec = new Vector2(orig.y, -orig.x);
        vec.Normalize();
        return vec * -1;
    }

  private Vector3[] vertices;

  public void GenerateMesh(){
    vertices = new Vector3[(sampleFrequency + 1) * 2];

    //iterate over our samples adding two vertices for each one
    for(int s = 0, i = 0; s <= sampleFrequency; s++, i += 2){
      float interval = s / (float)sampleFrequency;

      //get point along spline, and translate to local coords from world
      var point = transform.InverseTransformPoint(spline.GetPoint(interval));
      var direction = spline.GetDirection(interval);

      var perpendicularLeftVec = PerpendicularLeft(direction) * lineWidth;
      var perpendicularRightVec = PerpendicularRight(direction) * lineWidth;
      // var perpendicularVec = turnLeft ? PerpendicularLeft(diffVector) : PerpendicularRight(diffVector);

      vertices[i] = point + (Vector3)perpendicularLeftVec;
      vertices[i + 1] = point + (Vector3)perpendicularRightVec;
    }

    GetComponent<MeshFilter>().mesh = mesh = new Mesh();
    mesh.name = "Spline Mesh";

    mesh.vertices = vertices;

    //now figure out our triangles
    int [] triangles = new int[sampleFrequency * 6];
    for(int s = 0, ti = 0, vi = 0; s < sampleFrequency; s++, ti += 6, vi += 2){
      //first tri
      triangles[ti] = vi;
      triangles[ti + 1] = vi + 3;
      triangles[ti + 2] = vi + 1;
      //second matching tri
      triangles[ti + 3] = vi;
      triangles[ti + 4] = vi + 2;
      triangles[ti + 5] = vi + 3;
    }

    mesh.triangles = triangles;
    mesh.RecalculateNormals();

    Debug.Log("Generated Spline Mesh");
  }


}
1
DShook

J'ai eu ce problème avec Unity 2017.2. J'ai essayé de changer mes paramètres AA au maximum pour me débarrasser des irrégularités du rendu de ligne. Cela n'a pas fonctionné et c'était frustrant. 

Ma solution consistait à résoudre le problème que MSAA était désactivé sur l'appareil photo, car le rendu était différé. La caméra a un paramètre pour "utiliser les paramètres graphiques" qui n'aurait jamais dû être gâché, mais je suis débutant - je ne sais pas grand chose. J'ai changé le réglage pour "avancer" et mes jaggies ont disparu dans la brume. 

Si j'étais plus travailleur, je posterais des images avant et après.

0
jpgm