OpenGL GLSL Shader: Нарисуйте круг на плоском полигоне
Я ищу способ нарисовать что-то похожее на эти "ручки" с помощью шейдера GLSL
![alt text]()
Я хочу только рисовать цветные круги, и мое приложение не для ручки, а для фанкового индикатора прогресса. Можно ли рисовать круги (или, более конкретно, дуги) на плоском полигоне, только используя шейдер? И как начать процесс?
Ответы
Ответ 1
Да, это возможно! Проверьте этот GLSL script, который рисует несколько разных дуг:
#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
Да, это возможно.
Задайте координаты текстуры для многоугольника, чтобы вы могли получить доступ к относительным координатам в шейдере (например, от -1, -1 до 1,1 делает центр полигона 0,0). В шейдере фрагмента вычислите расстояние до центра с помощью пифагорана. Если расстояние меньше радиуса круга, пиксель находится внутри круга. Затем вы можете указать радиус для двух кругов и покрасить пиксель, если он находится внутри внешнего круга и вне внутреннего круга.
Если вы хотите покрасить только дугу, получите угол с atan (y, x) и проверьте, находится ли он в заданном диапазоне.
Вы также можете сглаживать круги, используя интерполяцию (шаг, плавность и т.д.) вместо простого, если при определении того, находится ли точка внутри круга.
Кроме того, в качестве оптимизации вам не нужно вычислять квадратный корень при расчете расстояния до центра, если вместо этого вы проверяете радиус ^ 2.