使用OpenGL ES 2.0着色器创建平滑纹理线条

6
我们有一个iOS绘图应用程序。目前,绘制使用OpenGL ES 1.1实现。我们使用一些算法来平滑线条,例如贝塞尔曲线。因此,当触摸事件发生时,我们从触摸事件点中获取一些点集(基于算法),并绘制这些点。我们还使用画笔纹理来使点具有更自然的外观。
我想知道是否可以在OpenGL ES 2.0着色器中实现这些算法。类似于调用OpenGL函数以绘制由触摸点组成的线条,并在输出上呈现平滑的画笔纹理曲线。
这里的点P0、P1、... P4是触摸事件,红色曲线上的点是输出点,T的步长使得相邻两点在曲线上的距离不大于1像素。
这里有一个解释贝塞尔曲线算法的链接: Bézier curve - Wikipedia, the free encyclopedia 非常感谢任何帮助。谢谢。

你能具体一点吗?如果我们不知道算法是什么,就无法告诉你是否可以在着色器中实现它! - user1118321
我们使用什么算法并不重要。关键在于着色器应该在输出上产生比输入点更多的点。我已经编辑了我的问题,并添加了一个Bezier算法的示例。 - Mikayel Aghasyan
1个回答

6
您不能在顶点着色器中生成新的顶点(您可以在几何着色器中执行此操作,但ES不支持)。输出顶点的数量始终与输入顶点的数量相同,您只能更改它们的位置(当然还有其他属性)。
因此,您必须绘制足够平滑曲线所需的足够多的顶点的线条。您可以始终放入相同的线条,将曲线参数值T作为1D顶点位置。在着色器中,您可以使用此输入位置(参数值)使用DeCasteljau算法(或其他方法)和P0到P4这些常量(在GLSL术语中为统一变量)计算曲线上的实际2D / 3D位置。
但我不确定是否真的比仅在CPU上计算这些点并将它们放入动态VBO中更划算。您节省的是从CPU复制曲线点到GPU和在CPU上的计算,但另一方面,您的顶点着色器要复杂得多。需要评估哪种方法更好。如果您需要每帧计算曲线点(因为控制点每帧都会改变)并且曲线具有相当高的细节,则可能不是一个坏主意。但否则,我认为它真的不值得。而且,您的着色器不太容易适应运行时变化的控制点/曲线度数。
但再次强调,您不能放入5个控制点并在GPU上生成N个曲线点。顶点着色器始终在单个顶点上工作,并产生单个顶点,就像片段着色器始终在单个片段(称为像素,尽管它还不是)上工作并产生单个(或无)片段一样。

非常感谢你提供的全面答案!我一直在寻找一种让代码更清晰、性能更好的方法。但是,现在看来似乎并不适用。 顺便说一下,你提出了一个很有趣的方法,通过传递代表T的1D线。我会思考一下这个方法。 - Mikayel Aghasyan

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接