Shader带你走进科技感十足的 “泰森多边形”
来源: | 作者:吴文明 | 发布时间: 2019-12-20 | 887 次浏览 | 分享到:
在生活中我们经常会看到一些基于泰森多边形的设计,如北京奥运会的水立方。在自然界中,泰森多边形更是随处可见,比如:蜻蜓的翅膀、树叶微观肌理等。那么我们该如何利用shader将其实现呢?



一、实现方法
1.1 什么是泰森多边形?

开始之前,我们先来了解一下泰森多边形的特征:
a. 每个泰森多边形内仅含有一个离散点数据
b. 泰森多边形内的点到相应离散点的距离最近
c. 位于泰森多边形边上的点到其两边的离散点距离相等

1.2 在shader中的实现方法

由其特征可知,我们需要先设置一组离散点,然后计算每一个像素与最近离散点的距离,也就是说我们需要遍历每个离散点,计算他们到当前像素点的距离,并把最近的那个距离保存下来。

伪代码如下:
float min_dist = 1.0; 
for (int i = 0; i < TOTAL_POINTS; i++) {
        float dist = distance(uv, points[i]);
        min_dist = min(min_dist, dist);
    }

当我们设置5个离散点,并把min_dist赋值给gl_FragColor时,就会得到类似下图的效果:



二、优化

上面的方法有些缺点,即当离散点数比较多时,我们虽然可以用for循环和数组来完成上述功能,但是遍历很多实例会显著降低着色器的性能,此外一个一个设置离散点也比较麻烦。

2.1 如何保证着色器的性能

保证着色器性能的方法就是把空间分割成网格。每个网格对应一个离散点,为避免网格交界区域的偏差,我们需要计算像素点到相邻网格中离散点的距离。每个像素点只需要计算到九个离散点的距离,即它所在的网格的离散点和相邻的八个网格的离散点。

——如何分割网格?
uv坐标默认是在0到1之间,如果我们把uv乘以一个系数,这样在0到1之间的图形就会重复生成网格。
a. 把uv乘以5,把坐标等比放大5倍:uv *= 5.0
b. 使用fract()函数单位化变量,使之在0.0到1.0之间:vec2 f_uv = fract(uv)
相关文章