形状与图案
常见形状
矩形
如图,若要画出上述矩形;正常思路就是扣去,,及的所有像素点,剩下的像素点就是我们想要的矩形区域;
具体到GLSL
中,可以使用step()
函数来进行扣去像素点的操作;如:
1 | step(b, y); |
就代表的像素点会返回;那么呢?如下:
1 | 1.0 - step(a, y); |
综上,利用step()
抠出一个矩形区域的做法为:
1 | step(b, y) - step(a, y) - step(d, x) - (1.0 - step(c, x)); |
当然,这样得到矩形区域的边缘会出现很明显的锯齿,可以使用smoothstep()
函数来替代step()
函数,得到一个比较平滑的边缘。
圆形
圆形区域就比较容易获取了,只需要计算像素点到圆心的距离就可以确定是不是在区域内了;
1 | 1.0 - step(r, length(pos - center)); |
正多边形
画出任意边数的正多边形可以根据一个距离场函数来进行;这个距离场函数实际上就是利用极坐标来进行计算的;
根据正多边形的内切圆或外接圆,将角度均分为相应的份数,在每份角度周期内圆心到边上的距离呈相同的规律变化。
如上图所示,以『正三角形』为例;在正三角形内得到一个内切圆,从圆心到顶点的边可以将内切圆均分为3
份(即)。以0
号边为起点,1
号边为终点,对应内切圆的,将该区间转化为,很自然地得到该段三角形边的极坐标方程为:
而对应到整个正三角形,关键就在于边上的点的角度到底位于区间的哪个位置。显然,只需要对角度取余即可。同理,该极坐标方程可以推广到任何正多边形;除此之外,也可以利用正多边形的外接圆来确定极坐标方程,精髓就在于确定一个周期内不变的三角函数关系即可!
上述极坐标方程只是确定了正多边形边上的点,若要得到一个正多边形区域,只需要满足到内切圆圆心的距离小于即可。
GLSL中的实现
1 | // 根据内切圆法得到正多边形的极坐标方程 |
上述方法可以画出一个正多边形区域,且对区域边缘部分进行了光滑处理;参数可以看做内切圆心(即多边形中心位置)到正多边形边上的向量,而参数则是内切圆的半径,稍微处理一下就可以当做多边形的边长。
关于使用内切圆来绘制正多边形,可以查看这个demo
:32. Polygon。
极坐标
就是当前点距离中心点的长度;而则是当前点相对于中心点的角度(弧度);只要图形边缘满足上述特点即可使用极坐标进行绘制,如最常见的圆形,可以使用如下极坐标方程:
是任意常数;
可以通过以下方式来计算某点的和:
1 | vec2 pos = p - center; // p是当前坐标点,center为图形中心点坐标 |
组合图形
- 叠加
- 扣除
图案(patterns)
广义指对某种器物的造型结构、色彩、纹饰进行工艺处理而事先设计的施工方案,制成图样,通称图案。有的器物(如某些木器家具等)除了造型结构,别无装饰纹样,亦属图案范畴(或称立体图案)。狭义则指器物上的装饰纹样和色彩而言。
—— https://baike.baidu.com/item/图案/52183
网格
通过将屏幕从水平和垂直方向分成一个的网格,其中每个网格单元可以进行图形的独立绘制,得到一个重复排列的图案;
假设最初得到的屏幕坐标为标准设备坐标(即坐标范围为),可以通过fract()
方法来进行网格单元的切割:
1 | vec2 num = vec2(n, m); // 水平及竖直方向单元的个数 |
通过上述方法可以将坐标分成n * m
个网格,其中每个网格内的坐标都是之间;然后对每个单元格进行相同的图形绘制,就可以得到重复填充的图案。可以查看这个根据网格进行重复填充的demo
:35. Pattern Test
不仅如此,还可以进一步获取每个单元格位于水平和竖直方向上的索引,然后进行偏移或其它操作,得到更加丰富的填充效果;