OpenGL GLSL着色器:在平面多边形上绘制圆形

11

我正在寻找一种使用GLSL着色器绘制类似于这些“旋钮”的方法。

alt text

我只想绘制彩色圆圈,我的应用程序不是为了旋钮而是为了时髦的进度条。是否有可能仅通过使用着色器在平面多边形上绘制圆(或更具体地说是弧线)?如何开始这个过程?

2个回答

11

是的,这是可能的。 将纹理坐标设置为多边形,以便您可以在着色器中访问相对坐标(例如,从-1,-1到1,1使多边形的中心为0,0)。在片段着色器中,用勾股定理计算距离中心的距离。 如果该距离小于圆的半径,则像素位于圆内。 您可以为两个圆指定半径,并在像素位于外部圆内且位于内部圆外时对其进行着色。

如果您只想着色弧线,请使用 atan(y,x)获取角度并检查其是否在给定范围内。

您还可以通过使用插值(step、smoothstep等)而不是简单的if来平滑圆圈,以确定点是否在圆内。

此外,作为优化,如果您对半径^2进行检查,则在计算到中心的距离时无需计算平方根。


8

是的,这是可能的!请检查此GLSL脚本,它绘制了几个不同的弧形:


#define between(v,x1,x2) (v>= x1 && v<=x2)
#define pi 3.141592653589793238462643383279

uniform sampler2D tex;

void main()
{
    vec2  pnt = vec2(0.5,0.5);
    float dr = 0.005;
    float fr = 0.15;
    float r1 = fr;
    float r2 = 1.5*fr;
    float r3 = 2.0*fr;
    float r4 = 2.5*fr;
    float r5 = 3.0*fr;
    float rp = distance(pnt,gl_TexCoord[0].xy);
    vec4 col1 = vec4(0.4,0.1,0.,1.);
    vec4 col2 = vec4(1.,1.,1.,1.);
    float angle = atan(gl_TexCoord[0].y,gl_TexCoord[0].x);
    vec4 rezcol;
    rezcol = (between(rp,r1-dr,r1+dr) && between(angle,-pi,pi))? col1:col2;
    rezcol = (between(rp,r2-dr,r2+dr) && between(angle,-pi,pi/3.1) && rezcol==col2)? col1:rezcol;
    rezcol = (between(rp,r3-dr,r3+dr) && between(angle,-pi,pi/4.6) && rezcol==col2)? col1:rezcol;
    rezcol = (between(rp,r4-dr,r4+dr) && between(angle,-pi,pi/8.8) && rezcol==col2)? col1:rezcol;
    rezcol = (between(rp,r5-dr,r5+dr) && between(angle,-pi,pi/22.8) && rezcol==col2)? col1:rezcol;
    gl_FragColor = rezcol;
}

这将导致显示如下图像:

alt text


这并不是最优雅的方法,我想 ;) 你在每个圆中都引入了一个分支(?:),这显然是可以避免的。另外,还可以通过一些平滑方法进行扩展。(仍然+1) - Kos
噢呦呦呦。加入一些平滑步进以提供抗锯齿效果。此外,你的圆形应该是用穿过圆心的线截断,而不是切线截断(圆的端点应该有90度角,与你的情况不同,尤其是最上面的)。 - the swine

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接