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.
着色器应避免在其代码中使用分支或条件语句,而是依赖 absstep函数来确定每个像素的颜色。

Theory

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

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

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更轻松!!

相关推荐
淹死在鱼塘的程序猿17 小时前
🚀 告别"一次性聊天":揭秘让 AI 智能体越用越聪明的秘密武器 —— Skills
前端·人工智能·agent
掘金安东尼17 小时前
OpenMUSE 全面详解:非扩散Transformer文生图开源基座(对标GPT Image 2)
前端·javascript·面试
~ rainbow~17 小时前
前端转型全栈(六)——深入浅出:文件上传的原理与进阶
前端·http·文件上传
我就是马云飞18 小时前
我废了!大厂10年的我面了20家公司,面试官让我回去等通知!
android·前端·程序员
yizhiyang18 小时前
ECharts实战:滑动缩放+选中背景高亮,打造高颜值统计图表
前端
猫山月18 小时前
Flutter路由演进路线(2026)
前端·flutter
We་ct18 小时前
LeetCode 322. 零钱兑换:动态规划入门实战
前端·算法·leetcode·typescript·动态规划
袋鱼不重18 小时前
Hermes Agent 直连飞书机器人
前端·后端·ai编程
不务正业的前端学徒18 小时前
Threejs,地图标签绘制,碰撞检测逻辑
前端
qq_120840937118 小时前
Three.js 工程向:GPU Overdraw 诊断与前端渲染优化
前端