美文网首页ShaderUnity Shader分享
Shader特效——“跳动的心”(转)

Shader特效——“跳动的心”(转)

作者: 树上的cat_ee3c | 来源:发表于2017-10-14 20:14 被阅读27次

转自:http://blog.csdn.net/panda1234lee/article/details/52024465

本文参考了ShaderToy的算法,对其原理进行了简单分析,并对代码进行精简

绘制心形

先看看关键代码

[cpp]view plaincopy

floatr = length(p);

floata = atan(p.x,p.y)/3.141593;

floath = abs(a);

floatd = (13.0*h - 22.0*h*h + 10.0*h*h*h)/(6.0-5.0*h);

// Red

vec3 hcol = vec3(1.0, 0.0, 0.0);

// Draw Heart

vec3 col = mix( u_bgColor.xyz, hcol, clamp( d-r, 0., 1.));

其中,p是片元坐标x,y从[0,1]域换算到[-1,1]的vec2形式,u_bgColor是白色的背景,a的含义不用解释了,值得一提的是a的范围是[-1/2, 1/2],需要对它取绝对值,原因是a为负数的话,计算出的d也为负数,那么会被mix函数所忽略的(所以我们常常使用clamp来截断),如图(颜色越浅表示d值越小,反之亦然):

当使用了a的绝对值,计算出的d效果如图:

该算法最关键的就是计算d的函数(看起来很普通,但是别急,接下来才是鉴证奇迹的时刻),该函数图如下所示:

注意定义域只取[-1/2, 1/2]。

接着,来看r,它是坐标p距离图像中心(0,0)的半径,同样值越小越白

最后,没错!现在就是鉴证奇迹的时刻,绘制心形我们只需要将d-r即可,如图所示。

但是很明显“心”偏下了一些,所以代码中通过p.y -= 0.25,对其进行了上移矫正。

但是现在仍然存在一个问题,就是❤的颜色向外越来越淡。

作者通过smoothstep来对(d-r)进行hermite插值,函数如图所示:

顺带提一下hermite插值,代码如下:

[cpp]view plaincopy

np.clip((t - down_edge)/(up_edge - down_edge), 0.0, 1.0)

smoothstep = t * t * (3.0 - 2.0 * t)

这样就出现了我们满意的❤了!很神奇有木有!

绘制“跳动”的效果

还是来看看关键的代码

[cpp]view plaincopy

floattt = mod(fElapsedTime, 1.5)/1.5;

tt = mod(fElapsedTime, _Duration)/_Duration;

floatss = pow(tt,.2)*0.5 + 0.5;

ss = 1.0 + ss*0.5*sin(tt*6.2831*3.0 + p.y*0.5)*exp(-tt*4.0);

其中fElapsedTime是程序运行的时间,以秒为单位。通过mod运算对时间进行周期性变换。

那ss又是什么鬼呢?我们来看看ss的函数图,来点直观的感受!

它是一个逐渐衰减的效果,很神奇有木有!

最后

综上,我们就可以简单的实现一个“跳动的心”的特效了,有木有感受到“数学之美”!

相关文章

网友评论

    本文标题:Shader特效——“跳动的心”(转)

    本文链接:https://www.haomeiwen.com/subject/idufuxtx.html