用Shader来绘制一个跳动的心脏。效果图
代码如下:
Shader"Custom/Heart"{
SubShader{
pass{
CGPROGRAM
#pragmavertexvert
#pragmafragmentfrag
#include"UnityCG.cginc"
//1.心形Shader的渲染需要拿到纹理坐标来进行渲染
//2.位置绑定
struct v2f{
float4 pos:POSITION;
float2 uv:TEXTCOORD0;
};
v2f vert(appdata_full v)
{
v2f o;
//坐标转换
o.pos =mul(UNITY_MATRIX_MVP,v.vertex);
//将心形中心点设置到纹理坐标中央(即(0.5,0.5)=>(0,0)),4为缩放比例
o.uv =4*v.texcoord.xy-fixed2(2,2);
returno;
}
float4 frag(v2f i):COLOR{
//背景颜色亮暗可以通过(1,.0.8,0.7)*(r(0到1之间的值))来达到
//距离中心越远r值越小
//length(q)q向量的的长度
fixed3 background = fixed3(1,0.8,0.7-0.07*i.uv.y)*(1-0.25*length(i.uv));
//控制心跳时间和函数横向长纵向短
//利用时间控制周期
float tt =fmod(_Time.y,1.0)/1.0;
float ss =pow(tt,.2)*.5+.5;
ss -= ss*0.2*sin(tt*6.2831*3.0)*exp(-tt*4.0);
i.uv *=float2(0.5,1.5) +float2(0.5, -0.5)/ss;
//心形函数
float a=abs(atan2(i.uv.y,i.uv.x))/3.141593;
float r =length(i.uv);
//利用函数调节心形函数
float d = (13*a-22*a*a+10*a*a*a)/(6-5*a);
fixed3 hcol =fixed3(1,0,0.3);
//背景颜色与心颜色过渡用Lerpsmoothstep做平滑处理
fixed3 col =lerp(background, hcol,smoothstep(-0.01,0.01, d-r));
return fixed4(col,1);
}
ENDCG
}
}
Fallback"Diffuse"
}
1.心形画法的原理
利用心形函数方程的特性
如图所示 心形曲线上的每个点到原点的距离与每个点到x轴的夹角的弧度制存在着一定的比例
我们可以利用这个来画心。
2. 坐标的设置
根据纹理坐标的性质,通过获取到纹理坐标,然后来设置坐标轴的原点位置以及在显示方面的大小。这里我们是把心形中心点设置到纹理坐标中央(即(0.5,0.5)=>(0,0)),4为缩放比例o.uv =4*v.texcoord.xy-fixed2(2,2);
3.图形的画制
atan2(i.uv.y,i.uv.x)求的是向量所对应的角度。求得的是弧度制的值,除以pi后得到的范围是[0,1];所以上面的函数就是求得平面上的坐标点所对应向量的角度(被映射到[0,1]之间);然后只需要把心形里面和外面渲染成不同的颜色即可。方法是用step方法,这里用smoothstep,使得边缘不那么硬, 然后结合lerp方法,如下:
float a=atan2(i.uv.y,i.uv.x)/3.141593;
float r =length(i.uv);
fixed3 col =lerp(background, hcol,smoothstep(-0.01,0.01, a-r));
这样只是画了半颗心,需要翻转xy轴,并取绝对值,
即可
4.利用函数调节心形
利用下面函数可以来调节心形
//利用函数调节心形函数
float d = (13*a-22*a*a+10*a*a*a)/(6-5*a);
5.心形跳动的算法
原理就是通过一定比例来改变心形的长宽的比例,然后让这种变化呈现一种周期性的变化。
我们这里有了一个接近于心跳规律的函数来控制。
//控制心跳时间和函数横向长纵向短
//利用时间控制周期
float tt =fmod(_Time.y,1.0)/1.0;
float ss =pow(tt,.2)*.5+.5;
ss -= ss*0.2*sin(tt*6.2831*3.0)*exp(-tt*4.0);
i.uv *=float2(0.5,1.5) +float2(0.5, -0.5)/ss;