【发布时间】:2010-11-29 04:54:21
【问题描述】:
我正在寻找一种方法来使用 GLSL 着色器绘制类似于这些“旋钮”的东西
我只想画彩色圆圈,我的应用程序不是用于旋钮而是用于时髦的进度表。是否可以仅使用着色器在平面多边形上绘制圆(或更具体地说是弧)?以及如何开始这一过程?
【问题讨论】:
我正在寻找一种方法来使用 GLSL 着色器绘制类似于这些“旋钮”的东西
我只想画彩色圆圈,我的应用程序不是用于旋钮而是用于时髦的进度表。是否可以仅使用着色器在平面多边形上绘制圆(或更具体地说是弧)?以及如何开始这一过程?
【问题讨论】:
是的,这是可能的。 将纹理坐标设置为多边形,以便您可以访问着色器中的相对坐标(例如,从 -1,-1 到 1,1 使多边形的中心为 0,0)。在片段着色器中,使用毕达哥拉斯计算到中心的距离。如果距离小于圆的半径,则像素在圆内。然后,您可以指定两个圆的半径,并在像素位于外圆内和内圆外时为其着色。
如果你只想给圆弧上色,用 atan(y,x) 获取角度并检查它是否在给定范围内。
在确定点是否在圆内时,您还可以使用插值(step、smoothstep 等)而不是简单的 if 来平滑圆。
此外,作为一种优化,如果您改为检查半径^2,则在计算到中心的距离时不需要计算平方根。
【讨论】:
是的,这是可能的!检查这个绘制几个不同弧线的 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;
}
产生这样的图像:
【讨论】: