开发者

openGL GLSL Shader: Draw a Circle on a flat polygon

I'm looking for a way to draw something similar to these "knobs" with an GLSL shader

openGL GLSL Shader: Draw a Circle on a flat polygon

I only want to draw the coloured circles, and my application is not for a knob rather开发者_高级运维 a funky progress meter. Is it possible to draw circles (or more specifically arcs) on a flat polygon just by using a shader? And how would one start the process?


Yes, it is possible. Set texture coordinates to the polygon so that you can access the relative coordinates in the shader (e.g. from -1,-1 to 1,1 makes the center of the polygon 0,0). In the fragment shader calculate the distance to the center with pythagoran. If the distance is less than the radius of the circle, the pixel is inside the circle. You can then specify radius for two circles and color the pixel if it is inside the outer circle and outside the inner circle.

If you want to color just an arc, get the angle with atan(y,x) and check if it is within a given range.

You can also smoothen the circles by using interpolation (step, smoothstep etc.) instead of a simple if when determining if the point is inside a circle.

Also as an optimization you don't need to calculate the square root when calculating the distance to the center if you instead check againsta radius^2.


Yes it is possible ! Check this GLSL script which draws several different arcs:


#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;
}

which results in such image:

openGL GLSL Shader: Draw a Circle on a flat polygon

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜