【问题标题】:GLSL Checkerboard PatternGLSL 棋盘格图案
【发布时间】:2022-01-11 20:52:28
【问题描述】:

我想用棋盘格遮住四边形:

f(P)=[地板(Px)+地板(Py)]mod2。

我的四边形是:

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

顶点着色器文件:

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

片段着色器文件为:

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

但我得到了这个:

似乎 mod 功能不起作用或者其他什么... 有什么帮助吗?

【问题讨论】:

  • 有趣。结果显示四边形实际上被渲染为两个三角形(左上/右下)。否则结果会更像一个平滑的棋盘格。如果是这样,您可以在片段着色器中使用阈值函数来获得正确的棋盘格。事实上,插值对于棋盘效果是无用的。

标签: glsl


【解决方案1】:

最好在片段着色器中计算这个效果,类似这样:

顶点程序 =>

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

片段程序 =>

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

输出 =>

祝你好运!

【讨论】:

  • 为什么不使用整数 x,y 并应用简单的位与(片段内不需要除法)
【解决方案2】:

在你的片段着色器中试试这个功能:

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

然后你可以在 main 中调用它:

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

只需传递您从顶点着色器获得的 x 和 y。之后您要做的就是在计算 vFragColor 时将其包含在内。

请记住,您可以通过修改 checkSize 值来更改检查大小。

【讨论】:

    【解决方案3】:

    您的代码所做的是计算因子 4 次(每个顶点一次,因为它是顶点着色器代码),然后对这些值进行插值(因为它已写入可变变量),然后将该变量作为颜色输出到片段着色器中.

    所以它不是那样工作的。您需要直接在片段着色器中进行计算。您可以使用片段着色器中的 gl_FragCoord 内置变量获取片段位置。

    【讨论】:

      【解决方案4】:

      我可以建议以下几点:

      float result = mod(dot(vec2(1.0), step(vec2(0.5), fract(v_uv * u_repeat))), 2.0);
      
      • v_uv 是 UV 值的 vec2,
      • u_repeat 是一个 vec2,表示每个轴应重复多少次模式。
      • result 为 0 或 1,你可以在 mix 函数中使用它来提供颜色,例如:
      gl_FragColor = mix(vec4(1.0, 1.0, 1.0, 1.0), vec4(0.0, 0.0, 0.0, 1.0) result);
      

      【讨论】:

        【解决方案5】:

        另一个不错的方法是平铺已知的图案(缩小)。假设您有一个方形画布:

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

        上面的代码为您提供了这种模式。

        下面的代码只需缩放 4.5 倍并取小数部分,即可将模式重复 4.5 次,从而每行有 9 个正方形。

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

        【讨论】:

          猜你喜欢
          • 2022-11-04
          • 2016-05-23
          • 1970-01-01
          • 2016-10-31
          • 2021-07-07
          • 2019-10-10
          • 2021-06-10
          • 2016-03-06
          • 1970-01-01
          相关资源
          最近更新 更多