GLSL Checkerboard Pattern

前端 未结 5 1060
情书的邮戳
情书的邮戳 2021-02-10 03:03

i want to shade the quad with checkers:

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

My quad is:

glBegin(GL_QUADS);    
  glVerte         


        
相关标签:
5条回答
  • 2021-02-10 03:37

    May I suggest the following:

    float result = mod(dot(vec2(1.0), step(vec2(0.5), fract(v_uv * u_repeat))), 2.0);
    
    • v_uv is a vec2 of UV values,
    • u_repeat is a vec2 of how many times the pattern should be repeated for each axis.
    • result is 0 or 1, you can use it in mix function to provide colors, for example:
    gl_FragColor = mix(vec4(1.0, 1.0, 1.0, 1.0), vec4(0.0, 0.0, 0.0, 1.0) result);
    
    0 讨论(0)
  • 2021-02-10 03:41

    What your code does is calculate the factor 4 times (once for each vertex, since it's vertex shader code) and then interpolate those values (because it's written into a varying varible) and then output that variable as color in the fragment shader.

    So it doesn't work that way. You need to do that calculation directly in the fragment shader. You can get the fragment position using the gl_FragCoord built-in variable in the fragment shader.

    0 讨论(0)
  • 2021-02-10 03:44

    It is better to calculate this effect in fragment shader, something like that:

    vertex program =>

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

    fragment program =>

    #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

    Good luck!

    0 讨论(0)
  • 2021-02-10 03:55

    Another nice way to do it is by just tiling a known pattern (zooming out). Assuming that you have a square canvas:

    void mainImage( out vec4 fragColor, in vec2 fragCoord )
    {
        // Normalized pixel coordinates (from 0 to 1)
        vec2 uv = fragCoord/iResolution.xy;
        uv -= 0.5; // moving the coordinate system to middle of screen
        // Output to screen
        fragColor = vec4(vec3(step(uv.x * uv.y, 0.)), 1.);
    }
    
    

    Code above gives you this kind of pattern. square pattern

    Code below by just zooming 4.5 times and taking the fractional part repeats the pattern 4.5 times resulting in 9 squares per row.

    void mainImage( out vec4 fragColor, in vec2 fragCoord )
    {
        // Normalized pixel coordinates (from 0 to 1)
        vec2 uv = fract(fragCoord/iResolution.xy * 4.5);
        uv -= 0.5; // moving the coordinate system to middle of screen
        // Output to screen
        fragColor = vec4(vec3(step(uv.x * uv.y, 0.)), 1.);
    }
    
    

    square pattern repeated

    0 讨论(0)
  • 2021-02-10 03:55

    Try this function in your fragment shader:

    vec3 checker(in float u, in float v)
    {
      float checkSize = 2;
      float fmodResult = mod(floor(checkSize * u) + floor(checkSize * v), 2.0);
      float fin = max(sign(fmodResult), 0.0);
      return vec3(fin, fin, fin);
    }
    

    Then in main you can call it using :

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

    And simply pass x and y you are getting from vertex shader. All you have to do after that is to include it when calculating your vFragColor.

    Keep in mind that you can change chec size simply by modifying checkSize value.

    0 讨论(0)
提交回复
热议问题