在opengl中使用重心坐标的消除锯齿线

时间:2016-08-26 04:42:25

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

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

请参阅下图中的问题: enter image description here

注意Rect 1中的锯齿状边缘。这是因为我没有对边缘BC和DE应用抗锯齿,因为这些是内部边缘。因为长度x非常小,所以边缘BC和DE上靠近顶点C和D的锯齿状边缘变得可见;这些锯齿状边缘的长度比长度x长。如果我对这两个边(BC和DE)应用消除锯齿,我会看到Rect 2.这是因为在抗锯齿期间的平滑过程会将alpha值0.0分配给位于边缘或非常靠近边缘的片段。所以消除锯齿的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 个答案:

答案 0 :(得分:0)

算法主要是声音,但您需要一些方法来区分内部边缘和外部边缘,这是简单几何体无法做到的。您需要复制顶点,以便有助于内部边缘的顶点可以具有一些唯一属性,因此它们看起来与外部边缘不同。那说,听起来很贵......

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