【问题标题】:Screen-space distance along line strip in GLSLGLSL中沿线带的屏幕空间距离
【发布时间】:2014-09-25 21:38:09
【问题描述】:

在渲染线条时,如何获取片段沿线条到整个线条起点的距离(以像素为单位)?

在 3D 中渲染两点之间的单个线段时,屏幕空间中这两个点之间的距离就是它们 2D 投影之间的欧几里得距离。如果我渲染这个片段,我可以为每个片段插入(GLSL 中的布局限定符 noperspective)从起点沿线的屏幕空间距离。

然而,当渲染一条线带时,这不起作用,因为在几何着色器中,我只有关于当前段的起点和终点的信息,而不是所有以前的段。所以我用上面的方法可以计算的只是每个片段到线段起点的距离,而不是到线段起点的距离。但这正是我想要实现的目标。

我需要它来做什么:风格化的线条渲染。例如,根据屏幕覆盖范围(以像素为单位的长度)为折线着色,每 50 个像素添加一个距离标记,沿线带交替多个纹理,...

我目前做的是:

  • 预先在 CPU 上投影线的每个点
  • 以像素为单位计算所有投影线段的长度
  • 将长度作为顶点属性存储在缓冲区中(顶点 0 的距离为 0,顶点 1 的长度为 0->1,顶点 2 的长度为 0->1 + 1->2,... )
  • 在几何着色器中,创建线段并使用在 CPU 上计算的距离
  • 为每个片段插入没有透视校正的值

这可行,但必须有更好的方法来做到这一点。每帧在 CPU 上投影几百或几千个线点是不可行的。在几何着色器中是否有一种聪明的方法来计算它?我所拥有的是当前线段起点和终点的世界空间位置,我有两个点到沿线的线带起点的世界空间距离(再次顶点属性 0, 0- >1, 0->1 + 1->2, ...) 并且我可以提供关于线带的任何其他统一数据(世界空间单位的总长度,线段数,...)。

编辑:我不想计算到线带起点的欧几里得距离,而是沿整条线的距离,即总和直到当前片段的所有投影线段的长度。

【问题讨论】:

  • 这在顶点或几何着色器中不会以任何合理的方式工作,因为这会引入不同着色器调用之间的依赖关系,因为您需要累积“先前”段的长度。您需要在渲染之前预先计算。这并不意味着这不能并行完成,因为您原则上可以并行计算每个段的长度,然后将它们分层汇总。这可以通过计算着色器来完成。使用带有变换反馈的多次传递也可能有效。但是这两种方法都不是直截了当的。

标签: opengl glsl geometry-shader


【解决方案1】:

我看到了两种方式:

您可以使用顶点着色器。添加线带的起始坐标作为线的每个顶点的附加值。然后顶点着色器可以计算到起点的距离,并将它们插值传递给片段着色器。在那里你必须重新调整它们以接收像素值。

或者,您可以使用制服告诉顶点着色器每个线条的起始坐标。在那里,您需要像转换顶点坐标一样转换它们并将它们移向片段着色器。在那里,您必须将它们转换为像素坐标并计算到实际片段的距离。

【讨论】:

  • 我认为您误解了我的问题,或者我误解了您的回答。我不想计算到线带起点的欧几里得距离,而是沿线的距离,即到当前片段的所有投影线段的长度之和。简单地改变起点对我没有任何好处。
【解决方案2】:

我以为我只是在这里遗漏了一些东西,我的任务可以通过简单的透视计算魔法来解决。感谢 derhass 指出我的探索毫无意义。

与往常一样,提出问题已经解决了一半。当您知道要查找什么(“行的连续参数化”)时,您可能会偶然发现paper

福雷斯特·科尔和亚当·芬克尔斯坦。高质量线条可见性的两种快速方法。 IEEE Transactions on Visualization and Computer Graphics 16(5),2010 年 2 月。

解决了这个问题。该解决方案类似于 derhass 已经提出的解决方案。 Cole 和 Finkelstein 使用他们在 GPU 上按帧计算的 segment atlas。它包括所有投影线点的列表(以及其他属性,例如可见性),以跟踪每个片段沿线的位置。该片段图集是在帧缓冲区中计算的,因为论文(草稿)可以追溯到 2009 年。在计算着色器中实现相同的方法并将结果存储在缓冲区中似乎是可行的方法。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-07-14
    • 2020-12-08
    • 2011-11-18
    • 2021-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多