很早以前做cocos2dx的时候就看到官方着色器代码中已经有了一个现成的心型代码,故而网上也是有很多基于这个代码的,不过我觉得那个例子并不方便理解,所以就动手写一个容易理解的心型,核心数学公式是利用了笛卡尔的心型公式r=a(1-sinθ)。首先是最终结果示意图
下面是完整的着色器代码:
Shader "Custom/Heart" {
Properties
{
_MainTex ("Base (RGB) Trans (A)", 2D) = "white" {}
}
CGINCLUDE
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
};
struct v2f {
float4 vertex : SV_POSITION;
half2 texcoord : TEXCOORD0;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = mul (UNITY_MATRIX_MVP, v.vertex);
o.texcoord = TRANSFORM_TEX(v.texcoord, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
//画心
float _x = i.texcoord.x - 0.5;
float _y = i.texcoord.y - 0.5;
float len = sqrt(_x*_x + _y*_y);
float atan_x_y = atan(_y/_x);
//距离远点
float r = 0.2*(1 - _y/len); <span style="white-space:pre"> </span>这里就是笛卡尔的心型公式,r是得到的距离,当当前片段小于该距离说明该片段处于心内部,这里没有使用其他花哨的技巧就一个if-else,是为了方便理解
if (len < r)
{
return float4(1, 0, 0, 1);
}
else
{
return float4(1, 1, 0, 1);
}
}
ENDCG
SubShader {
Tags { "Queue" = "Transparent" }
Pass
{
Cull Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
ENDCG
}
}
FallBack "Diffuse"
}
而关于笛卡尔心型的理解,网上已经有很好解释,这里就给一个链接吧:http://www.360doc.com/content/07/0203/21/4213_354845.shtml