如何使Line Renderer线条保持平坦?


10

我注意到,当我向Line Renderer线添加更多顶点时,该线会扭曲并不再是平滑线。

在此处输入图片说明

.GIF此处:http//i.imgur.com/hRAhCXM.gif

即使删除了所有材质,所有线条仍在同一z水平上,但这些线条似乎仍然扭曲。

我不知道为什么这样做,或者如何解决它,有什么建议吗?C#


LineRenderer用于定位其顶点的算法存在问题,该算法很难处理尖角。您可以通过添加更多点以四舍五入的方式来稍微改善它,但是我发现最可靠的方法是使用更好的算法为自己复制其功能,方法是创建具有所需顶点的动态网格物体,或者创造性地利用ParticleSystem绘制点链。
DMGregory

1
更新: Unity的更高版本(5 5+)对LineRenderer算法进行了改进,因此考虑使用LineRenderers的用户可能会发现现成的结果在本质上要好得多。
DMGregory

Answers:


11

问题基本上是这样的:

在此处输入图片说明

LineRenderer试图连接红点位置。它正在创建绿色顶点以制作网格。因此,最上面的部分看起来很棒。但是,然后LineRenderer尝试变得经济时,它将在第二个线段的末端重用一个线段的末端的顶点。当角度很大时,您会遇到问题。第二个线段被夹在相交处,因为其“端盖”与其他“端盖”不垂直。

解决方案是创建自己的线条渲染器,而不是使其如此经济。您可以通过生成动态网格来实现。网格将由一系列细四边形组成。对于每个线段,可以通过计算线的法线和指定的线宽来计算四边形的四个角:

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);

这里abcd补单线段的四个角落,就像上图中的绿色光点。这些顶点将被添加到网格中,并且您还将添加索引以将四个顶点变成两个三角形(因此,将添加六个索引,即abc和bdc)。

这显然变得相当复杂。我相信Unity像以前那样实现LineRenderer的另一个原因是,这样做避免了另一个问题。当开始绘制每个线段时,您将开始看到两个线段在哪里汇合在一起并形成一个丑陋的关节。有几种方法可以通过计算两条线之间的共享法线并将其顶点更新为共享法线来解决此问题,但这只能部分解决问题,因为您仍然可以轻松地夹住夹线。最可靠的解决方案是在关节处生成其他顶点以充当角。


1
您也可以使用统一线渲染器并插入其他点来创建小斜接,从而摆脱困境。只需将一点指向上一点即可到达下一点。
mklingen'2

很棒的解释字节,谢谢。我可能会尝试看看是否无法在每个角上生成更多的点,如果效果不佳,我会继续尝试制作一个动态网格物体。谢谢。
道格拉斯·加斯凯尔

1

我遇到了同样的问题,并且解决了这个问题,我添加了更多点以平滑边缘,这不是一个优雅的解决方案,而是简单而有效的解决方案。至少对我来说。我写了一个函数来做到这一点:

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;
}


0

解决不透明线条的一种方法是在每个关节处绘制一个圆。圆的直径必须等于线宽。这需要渲染一些额外的顶点,但看起来确实不错。然后,您也可以摆脱关节之间的共享法线。

这仍然需要您编写自己的渲染代码,而不是使用Unity Line Renderer。

我在http://u3d.as/nFE上做了一项可以做到这一点的资产


0

避免这种情况的方法是,我总是在LineRenderer.SetPosition()方法中将z位置设置为0。所以不要写

LineRenderer.SetPosition(i, myVector3);

我写

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

但这不是最佳解决方案,因为您仍然会得到这些奇怪的提示。我能想到的最好的解决方案是创建单独的行。这对我来说非常有效。希望这对您有帮助。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.