Mutable ripples by Jason Labbe

Jason Labbe的主页www.jasonlabbe3d.com

本作品的演示以及代码www.openprocessing.org

 

3D动画艺术家Jason Labbe曾参与《侏罗纪世界》、《复仇者联盟》、《变形金刚4》等电影的动画制作,自己也经常用processing和unity做一些艺术作品。今天我们为大家带来他最新的processing作品代码教学。

当小编看到这个作品效果时觉得很有趣,当打开代码之后发现,代码行数也不多。今天就精读一下分享给大家!

 

 

然后我们先说一下作者的实现思路:

1. 因为是做渐变效果,所以作者将一个立方体进行细分,利用15*15*15个小单位球体构成的。

 

2. 然后我们看到渐变效果形成了一个球体,距球体的球心的距离不同会有不同的色调和亮度,也就是说我们首先要定义球心位置,而且要计算小单位球体到球心位置的距离;根据这个距离,来确定色调和亮度。

 

3. 最后还有一个渐变效果是对于每个小单位球体,都是由小到大,再由大到小变化的。这一点我们自然想到要利用三角函数来实现这种自然、连续的变化。

 

4. 除此之外,立方体会根据鼠标位置而旋转,我们也要思考如何实现这部分。

 

 

1.将一个立方体进行细分

 

首先,我们定义大立方体和小单位球体的参数信息:

 

 

2.我们来绘制球体,并根据球心距来决定色调和亮度

 

首先,我们定义一个球心位置:

这里使用了一个noise()函数,只是为了产生随机值,如果在这里将nx ny nz换成固定值,你就会发现球心是固定的,就像这样:

这个演示定义球心为(50,50,50)

 

然后我们计算球心距:

这里x y z是循环内的变量,所代表的就是小单位球体的坐标;nx ny nz是之前定义的球心位置。dist()函数用于计算两点之间的距离。

 

之后我们要根据这个距离来确定色调和亮度,作者是这样定义的:

 

这里有两个变量frameCount(返回当前帧数)和mult(刚才计算的距离)。而且表达式看起来也十分复杂,看到之后可能一时间搞不懂为什么作者要这样写。

 

这个时候我们停下来思考一下,代表距离的mult已经能够完成渐变了,为什么还要用一个frameCount呢?不如我们把frameCount都改成0,然后 再次运行:

 

 

frameCount改成0

 

 

我们发现,渐变仍然存在,证明我们的思路是没问题的。变化是:渐变速度变慢了 / 色调集中在橘黄色区域不再变化。

 

我们再来看这两个表达式:

作者在这里使用的颜色模型是HSB模型,不同于RGB色彩模型,h s b 分别代表了色调、饱和度以及亮度。

 

首先我们目光放到colorHue,定义色调的这个变量,如果frameCount改成了0,那么因为mult是存在最大值和最小值的,所以在求余运算(%255)的时候,无法取遍0-255的所有值,而是集中在了橘黄色区间,导致色调变化不大。

 

同时因为colorHue的表达式少了一个“frameCount%255”,所以变化速度也降低了。

 

对于colorBright,当wave的次级函数offset去掉frameCount时,数值的变化速度显然也降低了。所以亮度变化也减慢了。

 

最终,总体视觉效果就发现,整体速度变慢,色调集中在某个区间。

 

这里我们可以学习到,在一些渐变效果或者动画效果中,frameCount是一个很实用的变量,它随程序运行不断增加。

 

 

之后我们需要将已经定义好色调、亮度的小单位球体绘制出来:

绘制很简单:

 

   sphere(blockSize*0.8);

 

但是绘制位置需要我们计算:

这里很容易理解,如果你了解这里的相关函数的话:

 

这里的pushMatrix()函数是用于坐标变换的,一般同popMatrix()来一起使用。这两个函数一起出现时,在两个函数区间之内可以定义自己的一套坐标系。通常与translate()一起使用。

而translate()是实现坐标变换,程序默认的坐标系是这样的:

 
 

不要惊讶,计算机内的默认坐标系就是这样的,不信你用一下微信截图看看像素值。

 

 

如果我们执行这样的translate()语句:

translate(屏幕中心x坐标,屏幕中心y坐标)

就会使得坐标系移位,将屏幕中心作为坐标系原点:

 

不要忘记在最后写下:

 

这样在这句函数之后的坐标系又会变回默认坐标系。

 

 

 

 

3.小单位球体的大小变化:三角函数

 

 

scale()是一个缩放函数,当参数是一个时,scale之后绘制的所有图形都会缩放该值。

 

 

4.鼠标控制

 

结合之前对translate()的解释,以及注释,可以尝试理解。并且可以运用到其他程序之中。

 

 

好的今天的代码检查就到此结束了,如有任何疑问,欢迎在下方留言。

 

如果你有看到喜欢的作品,欢迎发到留言区,我们会尝试联系作者进行授权,对代码进行拆解。