携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情
前面已经说了造型函数,看上去画的是线,但是原理已经说了,其实就是画面。判断点是否在图形内。
但是很多时候,我们要绘制的图形比较复杂,不可能一个个拆分出来然后还按顺序去画。我们先来看一个小技巧,或者说常用的绘制手段
乘法和加法
先说结论,之前我们造型函数返回值都是0或1,中间值先认为没有。 0 代表无,不在图形内,1代表有,在图形内。 加法表示并集,乘法表示交集。
现在假设有 A B 两个图形,我希望新的图形是这两个图形合在一起的结果,就是并集,在A 内或者在B内,我们只要用 A + B 即可,只有在某一个图形内就不会为0,这样就把并集的图形给画出来了,至于大于1的部分,看具体逻辑,一般来说是不影响的,如果担心有影响,可以用clamp函数进行处理.
现在,需求改了,要AB 图形的交集,那我们只需把A B结果相乘即可,只有两者都不为零结果才不会为0.
我们来实际操作一下,就简单一点画一个方一个圆。
其实我画方的方法已经用上了乘法原理。代码里是直接覆盖其效果,就是和加法一样,因为实际上差不多就是加法 我们改变27 28行代码为 一行。
color = mix(color, color2, square(st,.2) + circle(st,.23) );
可以看到结果有所变化,因为我之前的颜色分量有小于1的,所以有影响,不过这种影响是符合某种场景的,具体场景具体运用。
现在来看乘法
color = mix(color, color2, square(st,.2) * circle(st,.23) );
看了乘法的结果是不是觉得可以用来做裁剪,没错,且可以反向裁剪,因为结果都在01之间,所以只要用1 减,结果就能取反。
color = mix(color, color2, square(st,.2) * (1. - circle(st,.23) ) );
乘法和加法就这么简单。
周期
我们知道可以用三角函数来实现周期性,但是有时候我们需要的突变性的周期函数。这个时候一般就是用取余/取模的方式来实现。
这里就要用到两个函数 mod 和 fract,glsl没有取余操作符 。
mod 取余, fract 取小数部分
mod(a ,b) = a % b , fract(a) = a - floor(a)
我们就简单点画个方格。但是我不想修改我的造型函数,只要处理一下坐标即可。
st *= 5.; // 放大
color = mix(color, color2, square(fract(st)-.5,.6) * circle(fract(st)-.5,.5) );// 取小数部分,之后原点又变成了左下角,所以还要减 .5
我食言了,没有画出格子来,因为我这个周期函数,现在是水平和垂直都直接重复,没有反向。但是,也可以画出格子来,只要在一个周期内画出一个四格就可以了。
来画个格子,我们要的是斜对角是同一种颜色,所以我直接取 x y的乘积,同号自然为正,异号为负。
float sige(vec2 st){
return step(st.x * st.y, 0.) ;
}
....
color = mix(color, color2, sige(fract(st)-.5) );
今日份就先到这里,极坐标和距离下次再说。