2010-11-29 7 views
11

Je suis à la recherche d'un moyen de tirer quelque chose de semblable à ces « boutons » avec un shader GLSLopenGL GLSL Shader: dessiner un cercle sur un polygone plat

alt text

Je veux seulement attirer l'couleur cercles, et mon application n'est pas pour un potard plutôt un progrès funky. Est-il possible de dessiner des cercles (ou plus précisément des arcs) sur un polygone plat en utilisant simplement un shader? Et comment commencer le processus?

Répondre

8

Oui, c'est possible! Vérifiez ce script GLSL qui dessine plusieurs arcs différents:


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

qui se traduit par telle image:

alt text

+0

pas l'approche la plus élégante de tout, je dirais;) Vous présentez une branche (? :) par cercle, ce qui peut certainement être évité. En outre, pourrait être prolongée avec un peu de lissage. (Toujours, +1) – Kos

+0

Oyoyoy. Jetez dans un peu de smoothstep pour fournir antialiassant. En outre, vos cercles coupés avec une tangente, ils devraient être coupés avec une ligne qui traverse le centre du cercle (les extrémités des cercles devraient avoir des angles de 90 degrés, contrairement à votre cas, en particulier le plus haut). –

11

Oui, c'est possible. Définissez les coordonnées de texture sur le polygone pour pouvoir accéder aux coordonnées relatives dans le shader (par exemple, de -1, -1 à 1,1, le centre du polygone 0,0). Dans le fragment shader calculer la distance au centre avec pythagoran. Si la distance est inférieure au rayon du cercle, le pixel est à l'intérieur du cercle. Vous pouvez ensuite spécifier un rayon pour deux cercles et colorer le pixel s'il se trouve à l'intérieur du cercle extérieur et à l'extérieur du cercle intérieur.

Si vous voulez colorier juste un arc, obtenez l'angle avec atan (y, x) et vérifiez s'il se trouve dans une plage donnée.

Vous pouvez également lisser les cercles en utilisant l'interpolation (pas, smoothstep, etc.) au lieu d'un simple si lors de la détermination si le point est à l'intérieur d'un cercle.

Aussi, en tant qu'optimisation, vous n'avez pas besoin de calculer la racine carrée lorsque vous calculez la distance au centre si vous vérifiez plutôt à l'aide d'un rayon^2.

Questions connexes