Shader 编程:只用一个函数就能生成三角形、矩形等所有的正多边形

字节流动

共 3257字,需浏览 7分钟

 · 2023-08-08

前面发了一些关于 Shader 编程的文章,有读者反馈太碎片化了,希望这里能整理出来一个系列,方便系统的学习一下 Shader 编程。

由于主流的 Shader 编程网站,如 ShaderToy, gl-transitions 都是基于 GLSL 开发 Shader ,加上 MSL 和 GLSL 语法上差别不大,后面系列文章将以 GLSL 为主来介绍 Shader 编程。

后面 Shader 编程将使用 VSCode + ShaderToy 插件作为编程环境,步骤如下:

  1. 下载安装 VSCode https://code.visualstudio.com/download

  2. 安装 ShaderToy 插件;

  3. 新建以 .frag 为后缀名的文件,复制粘贴本文的代码;

  4. 当前代码,点击鼠标右键,选择 ShaderToy:Show GLSL Preview , 然后就可以愉快地调试特效了。


绘制多边形

绘制多边形的思路跟画圆的思路一样,圆形可以看做一个有正无穷边的多边形。有了这个思路你就可以明白,我们需要为每条边划分对应的弧度,弧度相同它就是正多边形。

直接上代码:

#define PI 3.1415926535897932384626433832795

float polygonSDF(vec2 uv, float radius, float sides){
  //  原点设置到中心位置
   uv = uv * 2.0 - 1.0;
   // 相对于原点的 atan,范围[-PI/2,PI/2]
   float angle = atan(uv.x, uv.y) + PI / 2.0;
   // 多边形每一条边占用的弧度
   float slice = PI * 2.0 / sides;
   // floor 向下取整来构造多边形的边
   // smoothstep 作为边缘平滑过渡
   return smoothstep(radius-0.005, radius + 0.005cos(floor(0.5 + angle / slice) * slice - angle) * length(uv));
}

void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
    vec2 uv = fragCoord / iResolution.x;
    float n = ceil(mod(iTime, 8.0)) + 2.0;

    vec3 color = vec3(0.0);

    float val = polygonSDF(uv,0.3,n);
    color = vec3(val);
    fragColor = vec4(color,1.0);
}

代码里比较关键的就是 atan、floor、cos 这三个函数,你可以停下来琢磨一下。

这个直接绘制成正多边形的效果

SDF 有向距离场

上节其实牵扯到 SDF 算法,因为后面涉及高级特效的时候会经常用到,这里先提前对它做个简单的介绍,先在心里有个概念。

SDF(Signed Distance Field 有向距离场)算法是一种用于生成、存储和渲染字形(或图形)的技术。

SDF 算法能够快速而高效地计算出给定点与字形(或图形)边界之间的有符号距离,从而可以用于各种应用,如字体渲染、图像处理、形状变形等。

SDF 算法的基本原理是将字形(或图形)表示为一张包含有符号距离值的纹理。每个像素都存储了该像素距离最近的字形(或图形)轮廓的距离,并用正负号表示内部和外部。具体步骤如下:

  1. 生成轮廓:将字形(或图形)转换为轮廓线,通常使用矢量图形描述,如 TrueType 字体或 SVG 图形。

  2. 计算距离场:为了生成有符号距离场,需要遍历像素,并计算每个像素到最近轮廓线的距离值。可以使用一种快速的近似算法,如距离变换算法(如 Chamfer Distance Transform)或区域增长算法。

  3. 构建 SDF 纹理:将每个像素的距离值存储为纹理数据。正距离值用白色表示,负距离值用黑色表示,灰色用于表示距离为零的轮廓线。

使用生成的 SDF 纹理,可以进行以下操作:

  • 字体渲染:通过采样和插值技术,在不同大小和分辨率的设备上高效地渲染字形。

  • 文字渲染效果:通过分析有符号距离场的值,可以实现一些特殊的字体效果,如描边、阴影、模糊等。

  • 图像处理:由于 SDF 纹理存储了距离信息,可以进行各种图像处理和操作,如形变、缩放、旋转等。

SDF 算法在实际应用中被广泛使用,尤其在移动设备和游戏开发中,因为其高效性和渲染质量。

后续安排

后面 Shader 编程系列文章大致安排:

  1. ShaderToy 内置全局变量

  2. 重要的内置函数

  3. 基本图形

  4. 距离场

  5. 噪声函数

  6. 基础特效…

  7. 转场特效…

  8. 高阶特效…

-- END --


进技术交流群,扫码添加我的微信:Byte-Flow



获取相关资料和源码



推荐:

抖音传送带特效是怎么实现的?

所有你想要的图片转场效果,都在这了

我用 OpenGL ES 给小姐姐做了几个抖音滤镜

别人用 Shader 画了个圆,你却只能画椭圆?

Shader 编程:GLSL 重要的内置函数

Shader 编程:解决图片拉伸变形问题

浏览 546
点赞
评论
收藏
分享

手机扫一扫分享

举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

举报