2011-01-14 15 views
4

i schattieren wollen das Quad mit Kontrolleure:GLSL Schachbrettmuster

f (P) = [Boden (Px) + Boden (Py)] mod2.

Mein Quad ist:

glBegin(GL_QUADS);  
    glVertex3f(0,0,0.0);  
    glVertex3f(4,0,0.0);  
    glVertex3f(4,4,0.0); 
    glVertex3f(0,4, 0.0); 
glEnd(); 

Die Vertex-Shader-Datei:

varying float factor; 
float x,y; 
void main(){ 
    x=floor(gl_Position.x); 
    y=floor(gl_Position.y); 
    factor = mod((x+y),2.0); 
} 

Und das Fragment-Shader-Datei ist:

varying float factor; 
void main(){ 
    gl_FragColor = vec4(factor,factor,factor,1.0); 
} 

Aber im diese bekommen:

alt text

Es scheint, dass die Mod-Funktion funktioniert nicht oder vielleicht etwas anderes ... Irgendwelche Hilfe?

+0

Interessant. Das Ergebnis zeigt, dass das Quad tatsächlich als zwei Dreiecke dargestellt wird (oben/unten rechts). Ansonsten wäre das Ergebnis mehr wie ein geglättetes Schachbrettmuster. Wenn dies der Fall wäre, könnten Sie eine Schwellwertfunktion in Ihrem Fragment-Shader verwenden, um ein richtiges Schachbrettmuster zu erhalten. So wie es ist, ist die Interpolation für einen Schachbrett-Effekt nutzlos. –

Antwort

14

Es ist besser, diesen Effekt in Fragment-Shader zu berechnen, so etwas wie das:

Vertex Programm =>

varying vec2 texCoord; 

void main(void) 
{ 
    gl_Position = vec4(gl_Vertex.xy, 0.0, 1.0); 
    gl_Position = sign(gl_Position); 

    texCoord = (vec2(gl_Position.x, gl_Position.y) 
      + vec2(1.0))/vec2(2.0);  
} 

Fragmentprogramm =>

#extension GL_EXT_gpu_shader4 : enable 
uniform sampler2D Texture0; 
varying vec2 texCoord; 

void main(void) 
{ 
    ivec2 size = textureSize2D(Texture0,0); 
    float total = floor(texCoord.x*float(size.x)) + 
        floor(texCoord.y*float(size.y)); 
    bool isEven = mod(total,2.0)==0.0; 
    vec4 col1 = vec4(0.0,0.0,0.0,1.0); 
    vec4 col2 = vec4(1.0,1.0,1.0,1.0); 
    gl_FragColor = (isEven)? col1:col2; 
} 

Output =>

alt text

Viel Glück!

+1

warum nicht Integer x, y verwenden und einfaches Bit AND (keine Division innerhalb Fragment) anwenden – Spektre

3

Was Ihr Code macht, ist den Faktor viermal zu berechnen (einmal für jeden Eckpunkt, da es Eckpunkt-Shader-Code ist) und dann diese Werte interpolieren (weil er in eine variierende Variable geschrieben wird) und dann diese Variable als Farbe im Fragment ausgeben Shader.

So funktioniert es nicht so. Sie müssen diese Berechnung direkt im Fragment-Shader durchführen. Sie können die Fragmentposition mithilfe der integrierten Variablen gl_FragCoord im Fragment-Shader abrufen.

2

diese Funktion in Ihrem Fragment-Shader Versuchen:

vec3 check = checker(fs_vertex_texture.x, fs_vertex_texture.y); 

und y Sie von Vertex-Shader werden immer passieren und einfach x:

vec3 checker(in float u, in float v) 
{ 
    float checkSize = 2; 
    float fmodResult = mod(floor(checkSize * u) + floor(checkSize * v), 2.0); 

    if (fmodResult < 1.0) { 
    return vec3(1, 1, 1); 
    } else { 
    return vec3(0, 0, 0); 
    } 
} 

dann in Haupt Sie es mit aufrufen können. Alles was Sie danach noch tun müssen ist, es bei der Berechnung von vFragColor einzubeziehen.

Beachten Sie, dass Sie die chec-Größe ändern können, indem Sie einfach den checkSize-Wert ändern.