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?
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:
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:
v = (p2 - p1)
(en bleu). Ensuite, faites pivoter ce vecteur de 90 degrés normal = v.y, -v.x
marqué en rouge.[i, w/2 + i, w/2 + i + 1]
où i
est l'index actuel et w
est le nombre total de sommets.[i, w/2 * i + 1, i + 1]
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");
}
}
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.