1. Shapes

主要记录常用的形状写法:方形,圆形和三角形。

片元着色器书写的时候,需要注意的两点:1. 浮点数记得加小数点;2. 分号不能少。

1.1. Rectangle

1.1.1. multiple

使用 uv 坐标的 x 和 y 分别与 特定的值进行 step 比较,然后让比较的结果相乘,利用 0 乘以任何值都为 0 的特性,把四边都变成黑色,中间的白色部分就形成了一个方形。

1.0 - st 计算的是上边和右边,因为 uv 的坐标原点在左下方。

step(0.4, st) 可以改成 step(vec2(0.4, 0.3), st),就能画长方形了。

vec2 st = gl_FragCoord.xy / u_resolution.xy;

// bottom-left
vec2 bl = step(0.4, st);
float pct = bl.x * bl.y;

// top-right
vec2 tr = step(0.4, 1.0 - st);
pct *= tr.x * tr.y;

vec3 color = vec3(pct);

gl_FragColor = vec4(color, 1.);

1.1.2. abs + max

uv 坐标的 x 和 y 分别减去 0.5,将原点移动到中间(-0.5 to 0.5),然后分别求绝对值,再取最大值,得到的结果与固定数值进行 step 比较,小于固定数值的部分显示黑色,其余部分显示白色。

max 直接拿最大值进行比较,避免了分别比较还要相乘的算法,更高效。

uv 坐标的 x 和 y 分别减去 0.5, 将原点移动到中间,然后分别求绝对值,一次性计算四边,只能画正方形。

vec2 st = gl_FragCoord.xy / u_resolution.xy;
float pct = step(0.1, max(abs(st.x - 0.5), abs(st.y - 0.5)));
vec3 color = vec3(pct);
gl_FragColor =vec4(color, 1.);

1.1.3. 结合两种写法的优点

vec2 st = gl_FragCoord.xy / u_resolution.xy;
vec2 uv = st - 0.5;
vec2 pct = step(abs(uv), vec2(0.2, 0.3));
float strength = 1. - pct.x * pct.y;
vec3 color = vec3(strength);
gl_FragColor =vec4(color, 1.);

1.2. Circle

1.2.1. distance

利用 distance 计算不同两点的距离(像素坐标和画布中心的距离)。length()函数内部只不过是用平方根(sqrt())计算斜边的方程。

就计算效率而言,sqrt()函数,以及所有依赖它的运算,都耗时耗力。

vec2 st = gl_FragCoord.xy / u_resolution.xy;

float r = distance(st, vec2(0.5));
float c = 1.0 - step(0.5, r);

vec3 color = vec3(c, 0.5, 0.5);

gl_FragColor = vec4(color, 1.0);

1.2.2. dot

dot() 点乘是另外一种用来高效计算圆形距离场的方式。

本质:distance = sqrt((x-a)² + (y-b)²) => (x-a)² + (y-b)² <= r²,其中 dot(dist, dist) = (x-a)² + (y-b)²

vec2 st = gl_FragCoord.xy / u_resolution.xy;

vec2 dist = st - 0.5;
float r = 1. - step(0.5 * 0.5, dot(dist, dist));

vec3 color = vec3(r, 0.1, 0.1);

gl_FragColor = vec4(color, 1.0);

1.2.3. polar

uniform vec2 u_resolution;
uniform float u_time;

vec2 cartesianToPolar(vec2 cartesian) {
  float radius = length(cartesian);
  float angle = atan(cartesian.y, cartesian.x);
  return vec2(radius, angle);
}


void main() {
  vec2 st = gl_FragCoord.xy / u_resolution.xy;
  vec2 center = vec2(0.5, 0.5);  // 圆心位置
  float radius = 0.4;  // 圆的半径

  // 将笛卡尔坐标转换为极坐标
  vec2 polar = cartesianToPolar(st - center);

  // 判断当前像素是否在圆内
  float insideCircle = step(polar.x, radius);

  // 设置圆的颜色
  vec3 color = vec3(1.0, 0.0, 0.0);  // 红色

  // 根据像素是否在圆内来确定最终颜色
  vec4 finalColor = vec4(color * insideCircle, 1.0);

  gl_FragColor = finalColor;
}

1.3. triangle

glsl

Copyright © tomgou 2022 all right reserved,powered by Gitbook该文章修订时间: 2023-05-06 17:53:39

results matching ""

    No results matching ""