Task
Try to fill pixels in red that are within
0.25
of the texture center in normalized coordinates.
尝试以标准设备坐标中心点0.25
为半径的圆内绘制成红色
Theory
函数介绍
1 length()
- 测量向量的长度
- 对于一个二维向量
vec2 v = vec2(x, y)
,其长度为sqrt(x*x + y*y)
。 - 对于一个三维向量
vec3 v = vec3(x, y, z)
,其长度为sqrt(x*x + y*y + z*z)
。
length()
应用: 画圆。 圆的定义就是:平面上所有到圆心距离相等的点的集合。
glsl
// 假设 uv 是从 (-1.0, -1.0) 到 (1.0, 1.0) 的坐标
uv *= 2.0;
uv -= 1.0;
// 圆的半径为0.5
float radius = 0.5;
// 计算当前片元坐标到原点的距离
float d = length(uv);
// 如果距离小于半径,则为白色,否则为黑色
vec3 color = vec3(step(d, radius));
// step(d, radius) 等价于 d <= radius ? 1.0 : 0.0
// 我们可以用 smoothstep 获得更平滑的边缘
// float smooth_edge = 1.0 - smoothstep(radius - 0.01, radius + 0.01, d);
// vec3 color = vec3(smooth_edge);
gl_FragColor = vec4(color, 1.0);
2 distance()
- 测量两点间的距离
distance(p1, p2)
: 用于计算两个点p1
和p2
之间的直线距离。
它计算的同样是欧几里得距离,公式如下:
distance(p1, p2) = sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2) + ...)
distance
应用:同样的画一个圆
glsl
// 假设 uv 是从 (0.0, 0.0) 到 (1.0, 1.0) 的坐标
vec2 center = vec2(0.5, 0.5);
float radius = 0.3;
// 计算当前片元坐标到指定圆心的距离
float d = distance(uv, center);
// 根据距离上色
vec3 color = vec3(step(d, radius));
gl_FragColor = vec4(color, 1.0);
总结
两个位置向量的差 (p1 - p2
),会得到一个从 p2
指向 p1
的新向量 。而这个新向量的长度 ,恰好就是 p1
和 p2
两点之间的距离。
这意味着,前面那个在任意位置画圆的例子,我们也可以这样写:
glsl
// ...
vec2 diff = uv - center;
float d = length(diff); // 效果与 distance(uv, center) 完全相同
Answer
glsl
uniform vec2 iResolution;
void main() {
vec2 uv = gl_FragCoord.xy / iResolution.xy;
// 假设 uv 是从 (-1.0, -1.0) 到 (1.0, 1.0) 的坐标
vec2 center = vec2(0.5, 0.5);
float radius = 0.25;
// 计算当前片元坐标到指定圆心的距离
float d = distance(uv, center);
// 根据距离上色
vec3 color = vec3(step(d, radius));
color.gb =vec2(0.0, 0.0);
gl_FragColor = vec4(color, 1.0);
}
效果

练习
最后
如果你觉得这篇文章有用,记得点赞、关注、收藏,学Shader更轻松!!