形状(二维)

162 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第11天,点击查看活动详情

前面已经说了造型函数,看上去画的是线,但是原理已经说了,其实就是画面。判断点是否在图形内。

但是很多时候,我们要绘制的图形比较复杂,不可能一个个拆分出来然后还按顺序去画。我们先来看一个小技巧,或者说常用的绘制手段

乘法和加法

先说结论,之前我们造型函数返回值都是0或1,中间值先认为没有。 0 代表无,不在图形内,1代表有,在图形内。 加法表示并集,乘法表示交集。

现在假设有 A B 两个图形,我希望新的图形是这两个图形合在一起的结果,就是并集,在A 内或者在B内,我们只要用 A + B 即可,只有在某一个图形内就不会为0,这样就把并集的图形给画出来了,至于大于1的部分,看具体逻辑,一般来说是不影响的,如果担心有影响,可以用clamp函数进行处理.

现在,需求改了,要AB 图形的交集,那我们只需把A B结果相乘即可,只有两者都不为零结果才不会为0.

我们来实际操作一下,就简单一点画一个方一个圆。

image.png

其实我画方的方法已经用上了乘法原理。代码里是直接覆盖其效果,就是和加法一样,因为实际上差不多就是加法 我们改变27 28行代码为 一行。

 color = mix(color, color2, square(st,.2) + circle(st,.23) );

可以看到结果有所变化,因为我之前的颜色分量有小于1的,所以有影响,不过这种影响是符合某种场景的,具体场景具体运用。

image.png

现在来看乘法

 color = mix(color, color2, square(st,.2) * circle(st,.23) );

image.png

看了乘法的结果是不是觉得可以用来做裁剪,没错,且可以反向裁剪,因为结果都在01之间,所以只要用1 减,结果就能取反。

 color = mix(color, color2, square(st,.2) * (1. - circle(st,.23) ) );

image.png

乘法和加法就这么简单。

周期

我们知道可以用三角函数来实现周期性,但是有时候我们需要的突变性的周期函数。这个时候一般就是用取余/取模的方式来实现。

这里就要用到两个函数 mod 和 fract,glsl没有取余操作符 。

mod 取余, fract 取小数部分 mod(a ,b) = a % b , fract(a) = a - floor(a) image.png

image.png

我们就简单点画个方格。但是我不想修改我的造型函数,只要处理一下坐标即可。

 st *= 5.; // 放大
 
  color = mix(color, color2, square(fract(st)-.5,.6) *  circle(fract(st)-.5,.5) );// 取小数部分,之后原点又变成了左下角,所以还要减 .5

我食言了,没有画出格子来,因为我这个周期函数,现在是水平和垂直都直接重复,没有反向。但是,也可以画出格子来,只要在一个周期内画出一个四格就可以了。

image.png

来画个格子,我们要的是斜对角是同一种颜色,所以我直接取 x y的乘积,同号自然为正,异号为负。

float sige(vec2 st){ 
	return step(st.x * st.y, 0.) ;	
}

....

    color = mix(color, color2, sige(fract(st)-.5)  );

image.png

image.png

今日份就先到这里,极坐标和距离下次再说。