shader——mod()函数

688 阅读3分钟

前言

今天我们来学习 shader 的——mod 函数。话不多说,直接开始。

puppy-3979350_1280.jpg

mod()

函数意义

用来求余数函数,返回两数相除的余数。

函数语法

float mod(float x, float y)
vec2 mod(vec2 x, vec2 y)
vec3 mod(vec3 x, vec3 y)
vec4 mod(vec4 x, vec4 y)

vec2 mod(vec2 x, float y)
vec3 mod(vec3 x, float y)
vec4 mod(vec4 x, float y)

函数值域

两个异号整数求余

  1. 符号规律(余数的符号)

mod(负,正)=正,mod(-x , y):所得到的值为正;

mod(正,负)=负,mod(x , -y):所得到的值为负;

结论:两个整数求余时,其值的符号为除数的符号。

  1. 取值规律:先将两个整数看作是正数,再作除法运算
  • 能整除时,其值为 0 (或没有显示)

  • 不能整除时,其值= 除数 ×(整商+1)-被除数

例:mod(36,-10)=-4 即:36 除以 10 的整数商为 3,加 1 后为 4;其与除数之积为 40;再与被除数之差为(40-36=4);取除数的符号。所以值为-4。

两个小数求余取值规律:

被除数-(整商 × 除数)

例:mod(9,1.2)=0.6 即:9 除以 1.2 其整商为 7;7 与除数 1.2 之积为 8.4;被除数 9 与 8.4 之差为 0.6。故结果为 0.6。

例:mod(9,2.2)=0.2 即:9 除以 2.2 其整商为 4;4 与除数 2.2 这积为 8.8;被除数 9 与 8.8 之差为 0.2,故结果为 0.2。

在 VB 中,定义为被除数和除数先四舍五入,然后再相除求余数:

Mod(1.4, 3.3):
// 首先对 1.4 和 3.3 进行四舍五入,得到 1 和 3。
// 然后计算 1 Mod 3,结果是 1。
Mod(2.6, 3.7):
// 首先对 2.6 和 3.7 进行四舍五入,得到 3 和 4。
// 然后计算 3 Mod 4,结果是 3

被除数小于等于除数的整数取值规律:

当被除数小于等于除数时,Mod 运算的结果就是被除数本身

例:mod(1,3)=1,mod(2,3)=2

函数图像

image.png

案例

绘制纵向格网

precision mediump float;   // 定义精度
uniform vec2 u_resolution; //画布参数
void main(void) {

  vec2 p = (gl_FragCoord.xy * 2.0 - u_resolution) /
           min(u_resolution.x, u_resolution.y); // uv坐标[-1,1]

  p *= 10.; //uv坐标改为 [-10,10]

  float t = mod(p.x, 2.); //得到10个0-1

  gl_FragColor = vec4(vec3(t), 1.0);
}

image.png

绘制纵向网格

precision mediump float;   // 定义精度
uniform vec2 u_resolution; //画布参数
void main(void) {

  vec2 p = (gl_FragCoord.xy * 2.0 - u_resolution) /
           min(u_resolution.x, u_resolution.y); // uv坐标[-1,1]

  p *= 10.;
  float t = mod(p.y, 2.);

  gl_FragColor = vec4(vec3(t), 1.0);
}

image.png

绘制网格

precision mediump float;   // 定义精度
uniform vec2 u_resolution; //画布参数
void main(void) {

  vec2 p = (gl_FragCoord.xy * 2.0 - u_resolution) /
           min(u_resolution.x, u_resolution.y); // uv坐标[-1,1]

  p *= 10.;
  float t1 = smoothstep(0., 0.1, mod(p.x, 1.));
  float t2 = smoothstep(0., 0.1, mod(p.y, 1.));
  gl_FragColor = vec4(vec3(t1 * t2), 1.0);
}

image.png

发光圆环

我们在之前发光圆环的案例上,利用 mod 函数实现 f 发不同颜色光的圆环。

precision mediump float;   // 定义精度
uniform vec2 u_resolution; //画布参数
uniform highp float u_time;
void main(void) {

  vec2 p = (gl_FragCoord.xy * 2.0 - u_resolution) /
           min(u_resolution.x, u_resolution.y); // uv坐标[-1,1]
  float d = 0.01 / abs(0.5 - length(p));        //绘制一个圆环
  float t = mod(u_time, 3.0);
  // 根据时间的不同去取不同的颜色                  // 对时间动态取余
  vec3 color;
  if (t < 1.0) {
    color = vec3(p.x, p.y, 1.0 - p.x - p.y);
  } else if (t < 2.0) {
    color = vec3(p.x, 1.0 - p.y, p.x + p.y);
  } else {
    color = vec3(1.0 - p.x, p.y, p.x + p.y - 1.0);
  }

  // 颜色赋值
  gl_FragColor = vec4(vec3(d) * color, 1.0);
}

20240530171412_rec_.gif

总结

以上便是关于 shader——mod 函数的分享,如有错误之处,欢迎大家留言指出。谢谢大家了。