【ShaderToy】跳动的心

写在前面

注:如果你还不了解ShaderToy,请看开篇。

作为ShaderToy系列的第一篇,我们先来点简单的。下面是效果:

(CSDN目前不能传gif文件了,暂时空缺,可以看下面的原shader效果,是一样的)

原Shader地址:https://www.shadertoy.com/view/XsfGRn

代码

我们使用了之前的开篇中的基础模板。这里仅仅给出main函数的代码:

vec4 main(vec2 fragCoord) { vec2 p = (2.0*fragCoord.xy-iResolution.xy)/min(iResolution.y,iResolution.x);p.y -= 0.25;// background colorvec3 bcol = vec3(1.0,0.8,0.7-0.07*p.y)*(1.0-0.25*length(p));// animatefloat tt = mod(iGlobalTime,1.5)/1.5;float ss = 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);p *= vec2(0.5,1.5) + ss*vec2(0.5,-0.5);// shapefloat a = atan(p.x,p.y)/3.141593;float r = length(p);float h = abs(a);float d = (13.0*h – 22.0*h*h + 10.0*h*h*h)/(6.0-5.0*h);// colorfloat s = 1.0-0.5*clamp(r/d,0.0,1.0);s = 0.75 + 0.75*p.x;s *= 1.0-0.25*r;s = 0.5 + 0.6*s;s *= 0.5+0.5*pow( 1.0-clamp(r/d, 0.0, 1.0 ), 0.1 );vec3 hcol = vec3(1.0,0.5*r,0.3)*s;vec3 col = mix( bcol, hcol, smoothstep( -0.01, 0.01, d-r) );return vec4(col,1.0);}

代码很短,但包含了一些数学公式的计算,不懂的就会觉得很难理解。我们把上面代码拆分成两个部分:背景颜色(bcol),心的颜色(hcol,包含了心的跳动):

背景颜色

这部分比较简单。这个背景实际上是一个某点为中心,中心最亮、向边缘逐渐变暗的背景,比较常见。但通常我们都是用美术给的纹理直接用,现在我们用纯数学计算来看看如何实现它!

首先,我们在看一个重要变量的计算——p。

vec2 p = (2.0*fragCoord.xy-iResolution.xy)/min(iResolution.y,iResolution.x);p.y -= 0.25;第一行中,代码计算了每一个像素点和屏幕中心点之间的方向向量。我们以图为例说明。

在p.y减去0.25之前,中心点即是屏幕中心,代码先计算了每个像素点到中心的方向(如左图),然后再除以屏幕的高度(或宽度)(如右图)。图例如下:

这样的计算结果可以保存每个像素点距离中心的方向、远近等信息。

在这个基础上,我们还可以移动中心点的位置来控制渐变。代码中是将y减去了0.25,即将中心点向上移动了屏幕高度的0.25/2=0.125个单位。

我们可以通过更改代码来看到这样的效果:

vec3 bcol = vec3(1.0,0.8,0.7-0.07*p.y)*(1.0-length(p));return vec4(bcol,1.0);

以上步骤即可得到屏幕上每一个点到中心点的方向、相对距离等信息。接下来,我们就可以根据这些信息计算背景颜色了:

// background colorvec3 bcol = vec3(1.0,0.8,0.7-0.07*p.y)*(1.0-0.25*length(p));bcol可以认为是一个主背景颜色和像素距离中心点远近值的乘积。其中,是我们对上一步得到的距离进行进一步计算,由于的值可能大于1(如果屏幕x轴大于y轴,那么p的x方向的绝对值有些会大于1;反之,如果屏幕y轴大于x轴,那么p的y方向的绝对值有些会大于1),因此,我们需要在的基础上乘以系数0.25。当然,0.25是经验值,我们可以把这个参数做成shader的一个属性,供调节。中,是背景主色调,我们同样可以把它做成一个shader属性。后面会给出。而在B通道上减去可以当成是一个轻微的效果修正,即在y方向上,可以有些许颜色变化,其中0.07也是一个经验值,可以更改。

决定了我们是使用背景颜色还是心的颜色。当它值为0时,表示该像素不在心形内,则使用背景颜色,返回1时,则使用心的颜色;否则,就在背景颜色和心的颜色之间进行插值。而的返回值范围就是[0, 1]。其实已经表明该像素是否在心形内(后面会讲原因):若 > 0,则在心形内,若的值在正负0左右波动,我们可以通过添加一个[-0.01, 0.01]范围内的平缓过渡,来平缓

表示该像素是否在心形内。相关代码如下:

// shapefloat a = atan(p.x,p.y)/3.141593;float r = length(p);float h = abs(a);float d = (13.0*h – 22.0*h*h + 10.0*h*h*h)/(6.0-5.0*h);我们先来看a的含义。它是该像素对应方向的反正切值和π相除的结果。,我们会得到下面的结果:

,一部分是完成的是一个简单的由中心向外渐变的颜色:

的结果如下:

s的计算如下:

切忌贪婪,恨不得一次玩遍所有传说中的好景点,

【ShaderToy】跳动的心

相关文章:

你感兴趣的文章:

标签云: