我正在使用 TriangleList 输出我的图元。大多数时候,我需要绘制矩形、三角形、圆形。有时我需要绘制非常细的三角形(例如宽度=2px)。我认为它应该看起来像一条线(几乎是一条线),但它看起来像单独的点:)
下图显示了我在说什么:
左侧的第一张图片显示了如何绘制矩形(从右上角逆时针)。然后你可以看到我称之为“dx”的矩形的“宽度”。
如何避免这种行为?我希望它看起来像一条直线(几乎是直线),而不是点:)
我正在使用 TriangleList 输出我的图元。大多数时候,我需要绘制矩形、三角形、圆形。有时我需要绘制非常细的三角形(例如宽度=2px)。我认为它应该看起来像一条线(几乎是一条线),但它看起来像单独的点:)
下图显示了我在说什么:
左侧的第一张图片显示了如何绘制矩形(从右上角逆时针)。然后你可以看到我称之为“dx”的矩形的“宽度”。
如何避免这种行为?我希望它看起来像一条直线(几乎是直线),而不是点:)
正如@BrettHale 提到的,这是一个别名问题。例如,
如果没有超级/多重采样,三角形只覆盖右下角像素的中心,只有它会接收颜色。真实像素具有区域,并且在完美的情况下,将接收与所覆盖区域相等的部分颜色。“抗锯齿”技术可减少由于未跨像素集成颜色而导致的锯齿效果。
让它看起来正确而又不至于太慢是很困难的。OpenGL 提供了GL_POLYGON_SMOOTH
,它保守地光栅化三角形并使用混合为每个像素绘制正确的颜色百分比。这很有效,直到您有重叠的三角形并且您遇到需要与顺序无关的透明度的透明度排序问题。一个简单且更强力的解决方案是渲染到更大的纹理,然后进行下采样。这基本上就是超级采样所做的,除了样本可以是“各向异性的”(不规则的),这会产生更好的结果。多重采样技术是自适应的并且更有效,例如仅在三角形边缘对像素进行超采样。使用 OpenGL 进行设置非常简单。
然而,当三角形区域接近零时,该区域也会消失,即使使用抗锯齿它仍然会完全消失(尽管会淡出而不是像素化)。虽然在物理上不正确,但您可能会使用最小 1 像素宽度的三角形,这样即使它是一个非常细的三角形,您也可以获得所需的线条。这是您自己的保守光栅化可能感兴趣的地方。
这是一般瘦三角形的问题。例如,在自适应细分中,当您有细 T 形路口时,它一直在发生。一种解决方案是绘制具有抗锯齿效果的边缘(您可以使用 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);
在画线之前,当你的三角形非常小时你会得到线......
当几何体变得小于单个像素时,这称为亚像素特征。如果您为非常细的三角形设置动画,您会看到像素进出。
尝试打开多重采样。大多数 GL 窗口库支持多重采样后缓冲区。您也可以在图形驱动程序设置中强制启用它。
如果三角形是由几何着色器生成的,那么您可以使三角形区域动态化。
例如,您可以使三角形宽度始终大于 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;
}