ABS - Rhomb

Task

Write a shader that draws the full screen rhombus.
编写一个绘制全屏菱形的着色器

Requirements

The shader should avoid using branching or conditional statements in its code, and instead rely on the abs and step functions to determine the color of each pixel.
着色器应避免在其代码中使用分支或条件语句,而是依赖 abs 和step函数来确定每个像素的颜色。

Theory

曼哈顿距离:菱形的数学本质

我们通过abs将所有象限的坐标折叠到第一象限,折叠后坐标的 x 和 y 分量相加:

glsl 复制代码
float d = abs_st.x + abs_st.y;
// 或者写成 float d = abs(st.x) + abs(st.y);

这个 d 值代表什么?它在数学上有一个响亮的名字:曼哈顿距离(Manhattan Distance) ,也叫 L1 范数。它表示从原点 (0,0) 到点 (x,y) 只允许沿着坐标轴方向移动所需的最短距离。

现在,我们来分析这个 d 值:

  • 在画布中心 (0,0),d = 0。
  • 随着点向外移动,d 值线性增加。
  • 所有满足 abs(st.x) + abs(st.y) = C(C为常数)的点,构成了一个等值线。

当 C = 0.5 时,这条等值线正好是连接 (0.5, 0), (0, 0.5), (-0.5, 0), (0, -0.5) 四个点的正菱形!

其它:

  • 正方形 (L∞ 范数/切比雪夫距离): d = max(abs(st.x), abs(st.y));
  • 圆形 (L2 范数/欧几里得距离): d = length(st); 或 d = sqrt(st.x*st.x + st.y*st.y);

Answer

glsl 复制代码
uniform vec2 iResolution;

void main() {
  vec2 uv = gl_FragCoord.xy / iResolution.xy;
  uv -= 0.5; // 坐标中心化 将坐标从 [0, 1] 映射到 [-0.5, 0.5]

  float t = abs(uv.x) + abs(uv.y);
  t = 1.0 - step(0.5, t);

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

效果

练习

## ABS - Rhomb

最后

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

相关推荐
object not found44 分钟前
WooCommerce 接入 KPay 后订单完成页不显示订单信息:returnUrl 动态参数问题解决
前端·wordpress·独立站支付
yume_sibai1 小时前
04-Nginx部署实战完全指南(前端部署 + 后端代理 + 监控告警 + 故障排查)
运维·前端·nginx
data analyse 4561 小时前
数据合规的同意记录怎么留存?
前端·人工智能·数据分析
linux_cfan1 小时前
videojs v10 源代码系列解读:35 · HLS 解析器:multivariant 与 media playlist
前端·javascript·音视频
IT_陈寒1 小时前
Redis键过期失效?这个坑我踩得明明白白
前端·人工智能·后端
web打印社区1 小时前
汽修 / 4S 店:维修工单、结算单网页怎么静默出纸
开发语言·前端·javascript·chrome·ecmascript
liangshanbo12151 小时前
Webpack的分包策略面试题
前端·webpack·node.js
ttwuai2 小时前
Golang Web后台管理框架推荐:Gin、GoFrame与数据面板项目怎么分
前端·golang·gin
广州华水科技2 小时前
北斗GNSS变形监测系统在水库安全监测中的应用与优势
前端