【问题标题】:Drawing aliased pixel-perfect lines in fragment shader?在片段着色器中绘制别名像素完美线?
【发布时间】:2019-10-23 09:39:22
【问题描述】:

我正在尝试使用片段着色器在 OpenGL 中绘制像素完美的线条。我有以下从this question 获得的片段着色器。然而,结果是 2 像素而不是 1 像素。

#version 330

layout(location=0) out vec4 frag_colour;

in vec4 color;

uniform vec2 positionA;
uniform vec2 positionB;
uniform int thickness;

float lineSegment(vec2 p, vec2 a, vec2 b, float thickness)
{
    vec2 pa = p - a;
    vec2 ba = b - a;

    float h = clamp( dot(pa,ba)/dot(ba,ba), 0.0, 1.0 );

    float k = length(pa - ba*h);

    return smoothstep(0.0, thickness, k);
}

void main()
{
    vec2 uv = gl_FragCoord.xy;

    frag_colour = mix(color,vec4(0),lineSegment(uv,positionA,positionB,thickness));
}

据我了解,这是因为无论“线”在哪里,从技术上讲,两侧的像素距离相同,所以如果我尝试移除任何类型的抗锯齿,它们都“在线” " 所以我的 1 像素宽的线最终变成了 2 像素。

您可以看到黄色水平线是 2 像素宽(将其与文本中的各个像素进行比较)。

我在网上到处尝试了一些其他的片段代码,它们都存在同样的问题。

如何在 GLSL 中绘制像素完美的锯齿线(非抗锯齿线)?

编辑 1 通过0.5f调整位置和粗细后,移动到像素的中心,对角线在每一种“台阶”上都有抗锯齿。

对角线:

【问题讨论】:

  • thickness 就像是一条线周围的半径。如果您指定 1 个像素,您将获得上方 1 个像素和下方 1 个像素,即总共 2 个像素。如果您使用 0.5px 半径,请确保在像素中心指定端点,以避免数值不稳定。
  • 谢谢@Nico,为水平/垂直线做了这件事。但是以一定角度延伸的线添加了抗锯齿功能。
  • 然后将smoothstep 替换为return k <= thickness ? 0 : 1
  • 就是这样@NicoSchertler。在有人解释之后总是很明显。如果您将其放入答案中,我会接受。

标签: opengl glsl fragment-shader


【解决方案1】:

也许这会有所帮助(在 shadertoy 中测试):

bool lineSegment(vec2 p, vec2 a, vec2 b, float thickness)
{
    vec2 pa = p - a;
    vec2 ba = b - a;
    float len = length(ba);
    vec2 dir = ba / len;
    float t = dot(pa, dir);
    vec2 n = vec2(-dir.y, dir.x);
    float factor = max(abs(n.x), abs(n.y));
    float distThreshold = (thickness - 1.0 + factor)*0.5;
    float proj = dot(n, pa);
    
    return (t > 0.0) && (t < len) && (proj <= distThreshold) && (proj > -distThreshold);
}

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    vec2 positionA = iResolution.xy * 0.5;
    vec2 positionB = iMouse.xy;
    float thickness = 1.0;
    
    fragColor = mix(vec4(0), vec4(1), float(lineSegment(fragCoord,positionA,positionB,thickness)));
}

以防万一,here's math.stackexchange 上的相关问题。

【讨论】:

    猜你喜欢
    • 2018-07-15
    • 1970-01-01
    • 2018-12-25
    • 2012-10-30
    • 2016-04-29
    • 2019-11-27
    • 2014-09-06
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多