源代码在这里,效果就是很多的蜂窝。个人是小白,想通过学习研究一下如何画出这样的图
uniform float time;
uniform float resolution ;
bool hex(vec2 p) {
//p.x *= 0.6*2.0;
//p.y += mod(floor(p.x), 2.0) * 0.5;
//p.y += 0.6;
//p = abs((mod(p, 1.0) - 0.5));
//return abs(max(p.x*1.5 + p.y, p.y*2.0) - 1.0) > 0.05;
return abs(p.y * 2.0 - 1.0) > 0.05;
}
vec3 palette(float i) {
return vec3(1.0, 1.0, 1.0);
}
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
bool h = hex(fragCoord.xy/iResolution.xy);
fragColor.rgb = vec3(h,h,h);
fragColor.a = 1.0;
}
一开始的代码就显得很复杂,所以一点一点来,这个就是很简单的在屏幕中间绘制一根横线。
然后将hex函数进行修改,通过一个max函数使得直线进行弯折。
bool hex(vec2 p) {
//p.x *= 0.6*2.0;
//p.y += mod(floor(p.x), 2.0) * 0.5;
//p.y += 0.6;
//p = abs((mod(p, 1.0) - 0.5));
return abs(max(p.x + p.y, p.y*2.0) - 1.0) > 0.05;
// return abs(p.y * 2.0 - 1.0) > 0.05;
}
效果如下 ,黑色部分就是返回false的部分,右边的向下弯折的线是x和y的和在1附近的部分
还可以把变量换成x,似乎更好理解,似乎我对x的变量会敏感一些,hh。
bool hex(vec2 p) {
//p.x *= 0.6*2.0;
//p.y += mod(floor(p.x), 2.0) * 0.5;
//p.y += 0.6;
//p = abs((mod(p, 1.0) - 0.5));
return abs(max(p.x + p.y, p.x*2.0) - 1.0) > 0.05;
// return abs(p.y * 2.0 - 1.0) > 0.05;
}
还是回来吧,其实这边x和y是对称的,通过将p.x乘以一个系数可以控制横着的位置的长度
bool hex(vec2 p) {
//p.x *= 0.6*2.0;
//p.y += mod(floor(p.x), 2.0) * 0.5;
//p.y += 0.6;
//p = abs((mod(p, 1.0) - 0.5));
return abs(max(p.x * 1.6 + p.y, p.y*2.0) - 1.0) > 0.05;
// return abs(p.y * 2.0 - 1.0) > 0.05;
}
p = abs((mod(p, 1.0) - 0.5));
这个函数是控制在0到0.5之间
bool hex(vec2 p) {
//p.x *= 0.6*2.0;
//p.y += mod(floor(p.x), 2.0) * 0.5;
//p.y += 0.6;
p = abs((mod(p, 1.0) - 0.5));
return abs(max(p.x * 1.6 + p.y, p.y*2.0) - 1.0) > 0.05;
// return abs(p.y * 2.0 - 1.0) > 0.05;
}
叠加之后就形成了一种对称的,abs同时对x和y进行操作,实际上就是横竖都进行了一种对称,
还是不太理解,就继续拆开
bool hex(vec2 p) {
//p.x *= 0.6*2.0;
//p.y += mod(floor(p.x), 2.0) * 0.5;
//p.y += 0.6;
p.x = (mod(p.x, 1.0) - 0.5);
return abs(max(p.x * 1.5 + p.y, p.y*2.0) - 1.0) > 0.05;
// return abs(p.y * 2.0 - 1.0) > 0.05;
}
只操作x方向,将其变为-0.5到0.5之间,
bool hex(vec2 p) {
//p.x *= 0.6*2.0;
//p.y += mod(floor(p.x), 2.0) * 0.5;
//p.y += 0.6;
p.x = (mod(p.x, 1.0) - 0.5);
return abs(max(p.x * 1.5 + p.y, p.y*2.0) - 1.0) > 0.05;
// return abs(p.y * 2.0 - 1.0) > 0.05;
}
效果是这样,就是将屏幕竖着一分为2,右边的部分和上面比较像, 因为实际是将x进行缩小了,对了上面的0.05是用来调节黑色宽度大小的。
再加上abs,形成x轴的对称
bool hex(vec2 p) {
//p.x *= 0.6*2.0;
//p.y += mod(floor(p.x), 2.0) * 0.5;
//p.y += 0.6;
p.x = abs(mod(p.x, 1.0) - 0.5);
return abs(max(p.x * 1.5 + p.y, p.y*2.0) - 1.0) > 0.05;
// return abs(p.y * 2.0 - 1.0) > 0.05;
}
y轴也是同理,这样就能够形成上方的情况了。
由于之前将屏幕的比例转为成了0到1的范围,这样只能展示1个,将其缩小一点
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
bool h = hex(fragCoord.xy/iResolution.xy);
fragColor.rgb = vec3(h,h,h);
fragColor.a = 1.0;
}
变成
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
bool h = hex(fragCoord.xy/iResolution.xy * 2.0);
fragColor.rgb = vec3(h,h,h);
fragColor.a = 1.0;
}
效果也变了
似乎还是不太够,干脆将范围扩大到0-4
void mainImage( out vec4 fragColor, in vec2 fragCoord ) {
bool h = hex(fragCoord.xy/iResolution.xy * 4.0);
fragColor.rgb = vec3(h,h,h);
fragColor.a = 1.0;
}
这就有问题了,不过这样也带来的思路,上图一共有4列,可以将偶数列向下移动一定的位置,将其缝合好。因为是按照一奇数一偶数的形式,所以要模上2,来形成分割,但是应该下移多少呢
我们回到上方的代码
bool hex(vec2 p) {
//p.x *= 0.6*2.0;
p.y += mod(floor(p.x), 2.0) * 0.5;
//p.y += floor(p.x);
//p.y += mod(floor(p.x), 2.0);
p = abs(mod(p, 1.0) - 0.5);
return abs(max(p.x * 1.5 + p.y, p.y*2.0) - 1.0) > 0.05;
// return abs(p.y * 2.0 - 1.0) > 0.05;
}
并添加一行,floor用于下取整,这样0-1的部分的y就不会增加,1-2的部分的y会增加1,但是增加1倍是没有用的,可以试一试下面的代码,会发现并没有任何变化,因为这样相当于将第二列整个向下移动了一整格。
p.y += mod(floor(p.x), 2.0);
所以再次来研究这个函数,
其实就是 x * 1.5 + y = 1.0 和 y * 2.0 = 1.0 的一个组合
return abs(max(p.x * 1.5 + p.y, p.y*2.0) - 1.0) > 0.05;
不妨再简单一点, 把abs去掉
return (max(p.x * 1.5 + p.y, p.y*2.0) - 1.0) > 0.05;
这样黑色的部分就是不满足情况的样子,就是双方取最小值,转折点分别在三分之一和三分之二
bool hex(vec2 p) {
//p.x *= 0.6*2.0;
//p.y += mod(floor(p.x), 2.0);
//p.y += floor(p.x);
//p.y += mod(floor(p.x), 2.0);
p = abs(mod(p, 1.0) - 0.5);
return abs(max(p.x * 1.5 + p.y, p.y*2.0) - 1.0) > 0.05;
// return abs(p.y * 2.0 - 1.0) > 0.05;
}
加上这一行时等于把范围限制到了0.5,原来的图被移到了右上角,并且在0.5的地方被切开了,那么此时的y值就是1.5 * x + y = 1.0 且 x = 0.5时候的y的值,即0.25,所以想通过移动达到闭合效果的话,将偶数列的位置下移0.5就可以,所以上方要*一个0.5,当然只要是0.5的倍数都是可以的。
具体函数和效果如下
bool hex(vec2 p) {
//p.x *= 0.6*2.0;
p.y += mod(floor(p.x), 2.0) * 0.5;
//p.y += floor(p.x);
//p.y += mod(floor(p.x), 2.0);
p = abs(mod(p, 1.0) - 0.5);
return abs(max(p.x * 1.5 + p.y, p.y*2.0) - 1.0) > 0.05;
// return abs(p.y * 2.0 - 1.0) > 0.05;
}
这样看着不错,不错有点扁平,那就可以将x进行一个拉伸,大小可以自我调控。
bool hex(vec2 p) {
p.x *= 0.6*2.5;
p.y += mod(floor(p.x), 2.0) * 0.5;
//p.y += floor(p.x);
//p.y += mod(floor(p.x), 2.0);
p = abs(mod(p, 1.0) - 0.5);
return abs(max(p.x * 1.5 + p.y, p.y*2.0) - 1.0) > 0.05;
// return abs(p.y * 2.0 - 1.0) > 0.05;
}
效果会好些。
ending