shader 函数——abs()

307 阅读3分钟

前言

今天我们来了解下 shader 中的函数——abs()。

istockphoto-1439709160-612x612.jpg

abs()

函数意义

求传入数字的绝对值,返回该数的绝对值

函数语法

float abs(float x)
vec2 abs(vec2 x)
vec3 abs(vec3 x)
vec4 abs(vec4 x)

注意:abs(vec2(x,y))将返回一个二维向量 vec2(abs(x), abs(y))

vec3 abs(vec3 x),vec4 abs(vec4 x)同理。

函数值域

  1. 当 x>0, abs(x)=x;
  2. 当 x=0, abs(x)=0;
  3. 当 x<0, abs(x)=-x;

函数图像

image.png

实例

颜色渐变

  1. 不使用 abs()函数
precision mediump float;   //指定浮点数精度为中等精度
uniform vec2 u_resolution; //画布参数
void main(void) {

  vec2 uv = (gl_FragCoord.xy * 2. - u_resolution.xy) /
            min(u_resolution.x, u_resolution.y); //将uv坐标轴固定在[-1,1]

  vec3 col =
      vec3(uv.x); //根据x轴的变化来实现颜色渐变,可以看到从黑色到白色的颜色渐变

  gl_FragColor = vec4(col, 1.0);
}

image.png

  1. 使用 abs()函数
precision mediump float;   //指定浮点数精度为中等精度
uniform vec2 u_resolution; //画布参数
void main(void) {

  vec2 uv = (gl_FragCoord.xy * 2. - u_resolution.xy) /
            min(u_resolution.x, u_resolution.y); //将uv坐标轴固定在[-1,1]

  //   vec3 col = vec3(uv.x);
  //根据x轴的变化来实现颜色渐变,可以看到从黑色到白色的颜色渐变

  vec3 col = vec3(abs(
      uv.x)); //使用abs()函数之后,我们的uv.x的变化范围由[-1,1]变为[0-1],我们可以看到颜色是从白到黑再到白

  gl_FragColor = vec4(col, 1.0);
}

image.png

使用 abs()绘制一个圆环

绘制一个发光圆,圆心位置最亮

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]

  //这一步我们将绘制一个发光圆,圆心位置最亮
  float t = 1. - length(p); // length是求长度的函数,我们后面会讲

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

image.png

使用 abs 函数

为什么使用 abs()能形成一个黑色圆环呢?

  1. 为什么我们需要将 1 .0 变为 0.5 呢?——因为 1.0 -length(p),不存在负数的情况,因为我们的 uv 范围是[-1, 1], 所以 length(p) 的最大值为 1
  2. 使用 abs()之后会发生什么?
    • 0.5 - length(p)
    • 在距离圆心 0 .5 的范围内,为正,因此在 0.5 的范围内,呈现白色。
    • 出了 0.5 的范围为负,因此为黑色。
    • 使用 abs 之后,为负的部分变为了正,因此又为白色了,只有 0.5 的那条线上为黑色
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]

  //这一步我们将绘制一个发光圆,圆心位置最亮
  //   float t = 1. - length(p); // length是求长度的函数,我们后面会讲

  //使用abs函数
  float t = abs(0.5 - length(p));

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


image.png

形成一个发光圆环

使用一个很小的数去除 使用 abs 函数 之后的值,因为 0.5 位置上距离为 0,然后便能得到一个无限大的数,其他位置会近似得到一个为 0 的数。因此便可以得到一个发光圆环。

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]


  float t = 0.01 / abs(0.5 - length(p));

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

image.png

总结

以上便是今天分享的 shader——abs()函数的全部内容。如有错误之处,欢迎大家留言指出,谢谢大家了。