OpenGL GLSL Shader: нарисовать круг на плоском многоугольнике - PullRequest
11 голосов
/ 29 ноября 2010

Я ищу способ нарисовать что-то похожее на эти "ручки" с помощью шейдера GLSL

alt text

Я хочу рисовать только цветные круги, и мое приложение предназначено не для ручки, а для быстрого индикатора прогресса. Можно ли нарисовать круги (или, более конкретно, дуги) на плоском многоугольнике, просто используя шейдер? И как начать процесс?

Ответы [ 2 ]

11 голосов
/ 29 ноября 2010

Да, это возможно.Задайте координаты текстуры для многоугольника, чтобы вы могли получить доступ к относительным координатам в шейдере (например, от -1, -1 до 1,1 делает центр многоугольника 0,0).В фрагменте шейдера вычислите расстояние до центра с помощью пифагорана.Если расстояние меньше радиуса круга, пиксель находится внутри круга.Затем вы можете указать радиус для двух окружностей и покрасить пиксель, если он находится внутри внешнего круга и вне внутреннего круга.

Если вы хотите покрасить только дугу, получите угол с atan (y, x)и проверьте, находится ли он в заданном диапазоне.

Вы также можете сгладить круги, используя интерполяцию (шаг, сглаживание и т. д.) вместо простого, если при определении, находится ли точка внутри окружности.

Кроме того, в качестве оптимизации вам не нужно вычислять квадратный корень при расчете расстояния до центра, если вместо этого вы снова проверяете радиус ^ 2.

8 голосов
/ 01 декабря 2010

Да, это возможно! Проверьте этот 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

...