【问题标题】:Anti-aliased lines using barycentric coordinates in opengl在opengl中使用重心坐标消除锯齿线
【发布时间】:2017-01-02 15:51:49
【问题描述】:

我通过连接两个三角形来绘制一条线段。三角形的每个顶点都获得一组唯一的坐标作为可变变量(vec3 vBC)。然后在片段着色器中,我为这个变量得到的值是一个插值,表明片段在三角形内的位置。我使用这个值来确定片段与三角形边缘的距离,这反过来又用于对边缘进行抗锯齿。

见下图问题:

注意 Rect 1 中的锯齿状边缘。这是因为我没有对边缘 BC 和 DE 应用抗锯齿,因为它们是内部边缘。由于长度 x 非常小,靠近顶点 C 和 D 的边 BC 和 DE 上的锯齿状边变得可见;这些锯齿状边缘的长度比长度 x 长。如果我对这两个边缘(BC 和 DE)应用抗锯齿,我会看到 Rect 2。这是因为抗锯齿期间的平滑过程将 0.0 的 alpha 值分配给位于或非常靠近边缘的片段。所以抗锯齿的 BC 和 DE 在内部引入了一条白色对角线。

所以我的问题是我如何才能平滑 Rect 1?

片段着色器:

varying vec4 DestinationColor;
varying vec2 TexCoordOut;
varying vec3 vBC;
uniform sampler2D Texture;
uniform int TexEnabled;
float edgeFactor();

void main() {
  if (TexEnabled == 1) {
     gl_FragColor = texture2D(Texture, TexCoordOut) * DestinationColor;
  } else{
     gl_FragColor = vec4(DestinationColor.xyz, edgeFactor());
  }
}

float edgeFactor() {
  vec3 d = fwidth(vBC);
  vec3 a3 = smoothstep(vec3(0.0), d*1.5, vBC);
  return a3.y;
};

在着色器代码中,a3.y 指的是一组坐标中的第二个值(顶点 D 或 C 与片段之间的距离),即 y 表示 D(0,1,0) 中的 1,第一个 0 和第二个 0 表示x 和 z 分别。

【问题讨论】:

  • "注意矩形 1 中的锯齿状边缘" 不,我只看到一个黑色矩形,两个角上有一些污迹。
  • 这不是我从 opengl 得到的原始输出。我只是试图显示锯齿状边缘的位置。那些“污迹”实际上是 BC 和 DE 线的锐利边缘。我希望你能在 BC 和 DE 线上看到锯齿状的边缘
  • "这不是我从 opengl 获得的原始输出。" 那么你如何期望有人注意到实际上并不存在的东西呢?您询问的是您提供的图像中未显示的锯齿状边缘。
  • 我认为我的解释和图像会很清楚。不管怎样,你现在明白我要表达的意思了吗?

标签: c++ opengl-es opengl-es-2.0 fragment-shader vertex-shader


【解决方案1】:

该算法大多是合理的,但是您需要一些方法来区分内部边缘和外部边缘,而这对于简单的几何图形是无法做到的。您需要复制顶点,以便构成内部边缘的顶点可以具有一些独特的属性,使它们看起来与外部边缘不同。也就是说,这听起来很贵......

创建一个小的纹理可能更简单,该纹理具有朝向边缘的透明 Alpha 值,该值应用于线宽,沿线宽重复。它可能比所有额外的每个顶点数据都快,尤其是在具有延迟几何处理的移动设备上。

【讨论】:

    猜你喜欢
    • 2012-02-10
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-06-07
    • 1970-01-01
    相关资源
    最近更新 更多