glsl蜂窝代码理解

Hexagon grid (shadertoy.com)

源代码在这里,效果就是很多的蜂窝。个人是小白,想通过学习研究一下如何画出这样的图

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 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值