很早以前做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