代码之家  ›  专栏  ›  技术社区  ›  Aran Mulholland JohnnyAce

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

  •  11
  • Aran Mulholland JohnnyAce  · 技术社区  · 14 年前

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

    alt text

    我只想画彩色圆圈,我的申请不是为了一个旋钮,而是一个时髦的进度表。仅仅使用材质球就可以在平面多边形上绘制圆(或者更具体地说是弧)吗?如何开始这个过程呢?

    2 回复  |  直到 14 年前
        1
  •  8
  •   Agnius Vasiliauskas    14 年前

    是的,这是可能的!选中此绘制多个不同圆弧的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

        2
  •  11
  •   msell    14 年前

    是的,这是可能的。 将纹理坐标设置为多边形,以便可以访问着色器中的相对坐标(例如,从-1,-1到1,1使多边形的中心为0,0)。在片段着色器中,使用毕达哥兰计算到中心的距离。如果距离小于圆的半径,则像素位于圆内。然后,可以为两个圆指定半径,如果像素位于外圆内部和外圆外部,则可以为其上色。

    如果你只想给一条弧线上色,用atan(y,x)得到角度并检查它是否在给定的范围内。

    在确定点是否在圆内时,也可以使用插值(步长、平滑步长等)而不是简单的if来平滑圆。

    另外,作为优化,在计算到中心的距离时不需要计算平方根,如果您改为再次选中半径^2。