你们中的某些人可能知道在点集之间绘制线段确实非常困难,尤其是当您想要宽线或可变宽度时。我必须采用最便宜的选择来实现细分市场。到目前为止,这意味着我正在使用斜接器将两个矩形连接起来(如下所述)。

斜接器增加的额外长度有时会很大,尤其是在锐角的情况下,我希望在可能的情况下使用圆角。没有足够的处理资源来计算更多的几何。

下面的图显示了片段函数之后可能发生的情况:

/>紫色代表两条线之间应保留的区域;

没有人知道一种在片段着色器中实现此圆形矩形的方法,即使在形状不是多边形的情况下纹理坐标非常有用。 />
我希望我可以在不相交的

上画一个圆,记住,不管它需要快什么。

评论

如果可以将原始线的坐标传递到片段着色器,则可以尝试查找从片段到原始相关线段的距离,然后丢弃距离线宽远的任何片段。

“我相信这是片段着色器的工作,因为我没有足够的处理资源来计算更多的几何图形。”考虑到大多数此类生产线系统仅使用CPU对其进行栅格化,因此我怀疑您有大量的处理资源来计算更多的几何图形。

@NicolBolas如果我只是渲染线条,我当然会,但是创建线条的模拟非常昂贵。

#1 楼

首先,要解决对速度和性能的担忧,您将必须像以往一样始终在质量和性能之间进行权衡。如果第一个版本看起来适合您的用例,而其他所有版本都慢得多,则您必须自己做出决定。但是,您实际上不会测量任何时差。但是由于执行此操作的各种方法并不难集成到现有的宽线渲染器中,因此仅测试实际的各种方法并获得一些时间测量值就不会太困难,尤其是使用OpenGL计时器查询(或与Direct3D等效的任何方法) )。

因此,让我们对您的情况进行一些可能的改进。从您的链接和说明看来,您正在使用基于经典几何着色器的方法进行宽线渲染,将每条线转换为屏幕对齐的四边形(或两个三角形),并根据所需的线宽计算顶点位置达到。我最近也建立了类似的东西,有几种方法可以提高质量。


正如您自己说的那样,由于您要加工任意圆角的形状,最好让片段着色器会找出确切的像素形状,而不是尝试近似几何着色器中的圆形中间区域。但是,该想法并非完全可行,可以通过调整该圆形部分的顶点数量来实现良好的可调整质量-速度折衷。但是,它也与您当前的方法一起存在一个问题,即它实际上需要知道线的相邻线才能计算中间部分,这使得很难将其放入仅可绘制所有阴影的现有着色器不可知的渲染系统中将这些线作为顶点对(更不用说线带/环了),因为您需要为每条线添加邻接信息。

如果只想通过简单的Alpha测试让Fragmet着色器完成这项工作,则生成一个与屏幕对齐的矩形,该矩形比该线稍大,即,该矩形跨端点的宽度一半,因此也覆盖了圆形端盖。在片段着色器中,您只需检查每个片段到实际直线上最近点的屏幕空间距离即可(从几何着色器转移到片段着色器作为变化)。并且只要该距离大于线宽(准确地说是线宽的一半),就可以对片段进行discard。这样,您基本上将为每条线渲染一个圆角框。

精确地说,将线渲染为三个四边形(即,单个带中有6个三角形)。 ednpoints的中间部分是一个矩形,两个端盖是矩形,从端点沿线的方向跨过一半的宽度。您可以进行这种分离,以使最右边的四个顶点各自的端点为变化值,而最左边的四个顶点为其各自的端点。这样,您就可以平滑地对中间部分的线点进行插值,并在盖帽部分进行钳制。 Alpha到Coverage),并使Alpha沿着线的最外层〜1像素粗边框从1变为0。甚至两次。这不仅可能导致减慢透支(并且显式丢弃会抑制早期的z测试),而且还会干扰如上所述的任何可能的基于alpha的抗锯齿。减轻这种情况的一种解决方案可能是实际上只是将完全未覆盖的线绘制为从一个端点到另一端点的矩形(即,就像您的第一张图片一样)。然后将连接点(即线的顶点)绘制为附加的圆形大点(即,使用类似的技术,使用几何体着色器将点转换为屏幕对齐的四边形,并在片段着色器中测试到实际点中心的距离获得像素完美的圆)。

它的优点是,您实际上可以使用模版测试仅在尚未绘制线集合其他部分的区域中绘制结缔部分,因此仅紫罗兰色区域,这将大大减少透支(以更复杂的渲染和每片段操作为代价)。如上所述,使用基于alpha的抗锯齿方法可以提供非常好的结果(但是,仍然存在一些细微的伪像的微小区域)。这种方法是在不执行任何抗锯齿或混合操作时将线段及其端盖绘制在一起的,但是我想要记住,如果这样做,它造成的伪影比单独的渲染要多。不过,我现在对此并没有花太多的想法,这可能值得进一步研究。但是,单独的解决方案还具有需要进行昂贵的片段测试并且仅在实际的连接区域中可能丢弃的优点,可以使用简单明了的片段着色器来渲染线条中间部分。 >这些只是我最近刚刚考虑并认为值得分享的一些想法。如前所述,必须评估它们是否适合您的用例,可能需要一些时间和质量度量。

评论


$ \ begingroup $
您能否在第二个想法上做更多的扩展?我以前使用过一个简单的模板缓冲区作为遮罩,但是从来没有做过这么复杂的事情,比如告诉GPU不要在同一对象已经绘制了片段的地方绘制片段。我将如何精确填充模板缓冲区?
$ \ endgroup $
–J.Doe
17年11月1日在16:38

$ \ begingroup $
就这么简单。如果您以前使用过模板缓冲区进行遮罩,那就是您要做的。您将其清除为全0,然后将测试配置为仅在0处成功,并为每个通过的片段写1(或其他值)。这样,每个像素仅写入一次。
$ \ endgroup $
–克里斯蒂安·劳(Christian Rau)
17年11月1日在16:41

$ \ begingroup $
当使用alpha-blending与最后描述的分离版本一起进行抗锯齿时,您不应对线中间部分进行测试,而应填充模板缓冲区,然后在绘制连接点时对其进行测试。
$ \ endgroup $
–克里斯蒂安·劳(Christian Rau)
17年11月1日在16:43