是否可以在片段着色器中绘制线条粗细?

Med*_*eda 20 opengl-es opengl-es-2.0

考虑到我用GL_LINES画线,我是否可以在片段着色器中添加线条粗细?我看到的大多数示例似乎只访问片段着色器中基元内的纹素,并且线条粗细着色器需要写入线基元外部的纹素以获得厚度.但是,如果可能的话,一个非常小的,基本的例子就会很棒.

def*_*hlt 19

片段着色器可以提供很多功能.看看有些人在做什么.我自己离这个级别很远,但这段代码可以给你一个想法:

#define resolution vec2(500.0, 500.0)
#define Thickness 0.003

float drawLine(vec2 p1, vec2 p2) {
  vec2 uv = gl_FragCoord.xy / resolution.xy;

  float a = abs(distance(p1, uv));
  float b = abs(distance(p2, uv));
  float c = abs(distance(p1, p2));

  if ( a >= c || b >=  c ) return 0.0;

  float p = (a + b + c) * 0.5;

  // median to (p1, p2) vector
  float h = 2 / c * sqrt( p * ( p - a) * ( p - b) * ( p - c));

  return mix(1.0, 0.0, smoothstep(0.5 * Thickness, 1.5 * Thickness, h));
}

void main()
{
  gl_FragColor = vec4(
      max(
        max(
          drawLine(vec2(0.1, 0.1), vec2(0.1, 0.9)),
          drawLine(vec2(0.1, 0.9), vec2(0.7, 0.5))),
        drawLine(vec2(0.1, 0.1), vec2(0.7, 0.5))));
}
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

另一种方法是检查texture2D附近像素的颜色 - 这样你可以使图像发光或变厚(例如,如果任何调整像素为白色 - 使当前像素为白色,如果邻近像素旁边是白色 - 制作当前像素灰色).

  • 虽然这"有效",但应该指出的是,这可能是世界上绘制三条线的效率最低的方式.在混合期间,99%的处理碎片被丢弃. (10认同)

ltj*_*jax 6

不,在片段着色器中不可能仅使用GL_LINES. 这是因为 GL 限制您只能在提交给光栅器的几何图形上进行绘制,因此您需要使用包含锯齿状原始线以及任​​何平滑顶点的几何图形。例如,您可以使用几何着色器将线扩展为围绕理想线(或者实际上是两个三角形)的四边形,这可以构成一条粗线。

一般来说,如果生成更大的几何体(包括全屏四边形),则可以使用片段着色器来绘制平滑的线条。

这是关于该主题的精彩讨论(带有代码示例)。

  • 永远不要说不,除非你能证明这一点 (5认同)

Dav*_*aun 5

这是我的方法。令 p1 和 p2 为定义直线的两个点,令 point 为要测量其与直线距离的点。点很可能是 gl_FragCoord.xy / 分辨率;

这是函数。

float distanceToLine(vec2 p1, vec2 p2, vec2 point) {
    float a = p1.y-p2.y;
    float b = p2.x-p1.x;
    return abs(a*point.x+b*point.y+p1.x*p2.y-p2.x*p1.y) / sqrt(a*a+b*b);
}
Run Code Online (Sandbox Code Playgroud)

然后在 mix 和 smoothstep 函数中使用它。

另请查看此答案: /sf/answers/647251601/