【问题标题】:Perfect filled triangle rendering algorithm?完美的填充三角形渲染算法?
【发布时间】:2012-07-26 04:29:32
【问题描述】:

我在哪里可以获得渲染填充三角形的算法? Edit3:我不能使用 OpenGL 来渲染它。我需要每像素的算法。

我的目标是从三角形渲染一个正多边形,所以如果我使用这个三角形填充算法,每个三角形的边缘不会重叠(或在它们之间产生间隙),因为如果我这样做会导致渲染错误使用例如 XOR 来渲染像素。

因此,渲染质量应该与 OpenGL 渲染相匹配,所以我应该能够定义 - 例如 - 一个具有 N 个顶点的圆,并且它可以正确地渲染为任意大小的圆;所以它不像某些三角形填充算法那样只使用整数坐标来渲染它。

我需要自己控制填充三角形的能力:我可以添加自己的逻辑来渲染每个单独的像素。所以我需要渲染背后的裸代码来完全控制它。它应该足够有效地绘制数以万计的三角形而无需等待超过一秒钟。 (我不确定它最多能有多快,但我希望它不会超过 10 秒)。

首选语言是 C++,但我可以根据需要转换其他语言。

如果没有免费的算法,我可以在哪里学习自己构建一个,这实际上有多难? (我=数学菜鸟)。

我添加了 OpenGL 标记,因为这与它有某种关联。

Edit2: 我在这里尝试了算法:http://joshbeam.com/articles/triangle_rasterization/ 但它似乎有点破损,这是一个带有 64 个三角形的圆圈:

但是如果你放大,你可以看到错误:

解释:有 2 个像素与其他三角形颜色重叠,这不应该发生! (或透明度或异或等效果会产生不良渲染)。

似乎错误在较小的圆圈上更明显。如果我想对像素进行 XOR 效果,这是不可接受的。

我可以做些什么来解决这些问题,这样它就可以完美地填充它而没有重叠的像素或间隙?

Edit4:我注意到渲染非常小的圆圈不是很好。我意识到这是因为坐标确实被转换为整数。如何将坐标视为浮点数并使其像在 OpenGL 中一样精确和完美地渲染圆?以下是小圆圈看起来有多糟糕的示例:

请注意 OpenGL 渲染是多么完美!这就是我想要实现的目标,而不使用 OpenGL。 注意:我不只是想渲染完美的圆形,而是任何多边形形状。

【问题讨论】:

  • 您可以通过以扫描线算法为起点来做到这一点。有代码教程在:cs.utah.edu/~xchen/columbia/session2/lec13/html/index.html
  • 如果你想从分数精度中获得最大的好处,你应该在扫描线光栅化过程中以某种方式使用它。例如。通过仅渲染像素中心被多边形覆盖的像素,或在边缘上进行某种形式的抗锯齿。
  • 您认为“算法”应该如何处理数学上属于多个三角形的中心像素,以满足您的要求(没有未填充的像素,没有多次绘制的像素)?
  • 巧妙地使用整数可以创造奇迹。
  • @AlexeyFrunze,如果您有解决方案,请随时回答这个问题。

标签: c++ language-agnostic geometry rendering


【解决方案1】:

总是有half-space method

【讨论】:

  • 这看起来很有趣。但是,我无法让代码工作......它呈现出完全的胡言乱语。另外,我不确定应该设置什么 stride 变量,目前我将其用作“每像素字节数”,知道吗?
  • stride 通常是目标位图的像素宽度。 colorBuffer += stride 实质上在位图中向下移动了一行。
  • 我想到了这一点,但是当我设置 stride = width 时它只是崩溃了......如果我访问缓冲区而没有像这样的指针诡计,也许我可以修复它,让我们看看......
【解决方案2】:

OpenGL 使用 GPU 来执行这项工作。这在硬件中被加速,称为光栅化。 据我所知,硬件实现是基于扫描线算法的。

【讨论】:

    【解决方案3】:

    这通常是通过创建轮廓然后填充水平线来完成的。有关详细信息,请参阅此链接 - http://joshbeam.com/articles/triangle_rasterization/

    编辑:我认为这不会产生您所追求的孤立像素,每一行都应该有一个像素。

    【讨论】:

    • 这看起来很有希望,在我的第一次测试中,每一行都没有像素;看起来像正确的算法!很快就会用精确的圆圈进行测试。
    • 查看我的编辑,很遗憾,它没有完美运行!你知道如何解决它吗?
    • 我已经很久没有做过这种事情了,但如果我没记错的话,你可以根据你画线的方向得到不同的结果。对于圆圈,您应该利用对称性,至少 8 倍,并且只计算第零个八分圆(从 y=0 到 y=x)中的轮廓。
    • 圆形只是一个例子,我需要它来处理任何多边形形状。
    【解决方案4】:

    您的问题看起来很像共享同一边的三角形所遇到的问题。共享边的三角形所做的是允许一个三角形占据空间,而另一个必须将其留空。

    在使用图形卡时,通常通过应用从左到右的绘制顺序来获得此行为,同时还启用 z 缓冲区测试或测试是否曾经绘制过像素。因此,如果已经设置了具有相同 z 值的像素,则不允许更改像素。

    在您的圆圈示例中,两个相邻圆段的线不准确。您必须检查边缘的计算方式是否不同以及原因。

    每当您绘制两个不同的形状并看到类似的东西时,您可以修复您的模型(因此它们共享所有边缘顶点),进行 z 缓冲区测试或颜色测试。

    您还可以通过使用具有更高分辨率的子缓冲区绘制边缘并对其进行下采样来最小化这种影响。由于这不会影响整个区域,因此与对整个场景进行下采样相比,它在空间和时间方面更具成本效益。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-25
      • 2012-06-23
      • 1970-01-01
      • 2021-04-08
      • 1970-01-01
      • 2014-01-01
      相关资源
      最近更新 更多