OpenGL:用TriangleList绘制非常薄的三角形变成点

时间:2015-05-24 05:37:35

标签: opengl gl-triangle-strip

我使用TriangleList输出我的基元。大多数时候我需要绘制矩形,三角形,圆形。我不时需要绘制非常薄的三角形(例如宽度= 2px)。我认为它应该看起来像一条线(几乎是一条线),但它看起来像是单独的点:))

下图显示了我在谈论的内容:

enter image description here

左侧的第一张照片显示了如何绘制一个矩形(逆时针,从右上角)。然后你可以看到"宽度"我称之为#34; dx"。

的矩形

如何避免这种行为?我看起来像一条直线(几乎是直线),而不是点:)

4 个答案:

答案 0 :(得分:4)

正如@BrettHale所提到的,这是一个别名问题。例如,

enter image description here

如果没有超级/多重采样,三角形只会覆盖右下角像素的中心,只会接收颜色。真实像素具有面积并且在完美情况下,将接收等于所覆盖区域的一部分颜色。 “抗锯齿”技术可以减少因不在像素之间集成颜色而导致的aliasing效果。

enter image description here

让它看起来正确而不会非常慢,这很难。 OpenGL提供GL_POLYGON_SMOOTH保守地光栅化三角形,并使用混合为每个像素绘制正确的颜色百分比。这种方法很有效,直到您有重叠的三角形,并且您遇到需要order-independent transparency的透明度排序问题。一个简单而更强力的解决方案是渲染更大的纹理然后下采样。这基本上是超级采样所做的,除了样本可以是“各向异性的”(不规则的),这会产生更好的结果。多重采样技术是自适应的并且更有效,例如,仅在三角形边缘处的超采样像素。这对set this up with OpenGL来说相当简单。

然而,当三角形区域接近于零时,该区域也会出现并且即使使用抗锯齿也会完全消失(尽管会逐渐消失而不是变成像素化)。虽然物理上不正确,但您可以使用最小1像素宽度的三角形,这样即使它是一个非常薄的三角形,您也可以获得所需的线条。这是您自己感兴趣conservative rasterization的地方。

enter image description here

答案 1 :(得分:1)

当几何体变得小于单个像素时,这称为子像素特征。如果您为非常薄的三角形设置动画,则会看到像素弹出和弹出。

尝试打开多次采样。大多数GL窗口库支持多重采样后台缓冲区。您也可以在图形驱动程序设置中强制它。

答案 2 :(得分:0)

一般来说,这是瘦三角形的问题。例如,在自适应细分中,当你有瘦的丁字裤时,它会一直发生。一种解决方案是绘制边缘(您可以使用GL_LINE_STRIP)并具有抗锯齿效果您可以拥有:

            Gl.glShadeModel(Gl.GL_SMOOTH);
            Gl.glEnable(Gl.GL_LINE_SMOOTH);
            Gl.glEnable(Gl.GL_BLEND);
            Gl.glBlendFunc(Gl.GL_SRC_ALPHA, Gl.GL_ONE_MINUS_SRC_ALPHA);
            Gl.glHint(Gl.GL_LINE_SMOOTH_HINT, Gl.GL_DONT_CARE);

在绘制线条之前,当三角形非常小时,你会得到线条......

答案 3 :(得分:0)

如果三角形是由几何着色器生成的,则可以使三角形区域动态化。
例如,您可以使三角形的宽度始终大于1px。

// ndc coord is range from -1.0 to 1.0 and the screen width is 1920.
float pixel_unit = 2.0 / 1920.0;
vec2 center = 0.5 * (triangle[0].xy + triangle[1].xy );

// Remember to divide the w component.
float triangle_width = (triangle[0].xy - center)/triangle[0].w;
float scale_ratio = pixel_unit / triangle_width;
if (scale_ratio > 1.0){
triagle[0].xy = (triangle[0].xy - center)  * scale_ratio + center;
triagle[1].xy = (triangle[1].xy - center)  * scale_ratio + center;
}