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

相关推荐
天下权1 分钟前
抛弃脚手架!手写极简Vue2实现原理
前端
张元清3 分钟前
Neant:0心智负担的React状态管理库
前端·javascript·面试
阳树阳树4 分钟前
小程序蓝牙API能力探索 1——蓝牙协议发展历史
前端
阿华的代码王国6 分钟前
【Android】PopupWindow实现长按菜单
android·xml·java·前端·后端
ygming15 分钟前
Q51- code295- 数据流的中位数 + Q52- code767- 重构字符串
前端
袋鱼不重17 分钟前
手把手搭建Vue轮子从0到1:4. Reactivity 模块的实现
前端·vue.js·源码
!win !17 分钟前
免费的个人网站托管-GitHub Pages篇
前端·开发工具
xw519 分钟前
免费的个人网站托管-GitHub Pages篇
前端·github
阿星AI工作室20 分钟前
扣子可以发布到小米搞钱了!手把手教程来了丨coze开发者瓜分亿级流量池指南
前端·人工智能·后端
小华同学ai20 分钟前
GitHub 开源爆款工具|MediaCrawler:程序员零门槛采集抖音/小红书/B站等社交评论,30K star 背后的场景实战揭秘!
前端·后端·github