绘制一个正六边形的Shader
最终效果如图
基本原理是当前片源UV坐标和fixed2(0.5 0.5)的距离与离其最近的正六边形的中心点UV坐标的距离之间的差的绝对值是否小于边缘的宽度。
此做法经过扩展可以用来做UI的正六边形遮罩等功能。下面是shader的具体实现。
具体算法请结合上一篇关于六边形坐标系的文章。六边形网格向量工具
// Unlit shader. Simplest possible colored shader.
// - no lighting
// - no lightmap support
// - no texture
Shader "Unlit/Hex" {
Properties {
_Color ("Main Color", Color) = (1,1,1,1)
}
SubShader {
Tags {"Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent"}
LOD 100
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Pass {
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma target 2.0
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata_t {
float4 vertex : POSITION;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f {
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(0)
UNITY_VERTEX_OUTPUT_STEREO
};
fixed4 _Color;
v2f vert (appdata_t v)
{
v2f o;
UNITY_SETUP_INSTANCE_ID(v);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.texcoord;
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f input) : COLOR
{
fixed4 col = _Color;
fixed3 n[6] = {
fixed3(0, 1, -1),
fixed3(1, 0, -1),
fixed3(-1, 1, 0),
fixed3(1, -1, 0),
fixed3(-1, 0, 1),
fixed3(0, -1, 1),
};
fixed c = 1;
fixed disc = distance(input.uv.xy,fixed2(0.5,0.5));
fixed mindis = 1;
for(int i=0; i<6; i++){
fixed2 pos = fixed2(0.5+ 0.5 * 1.73205080756887 * (n[i].x + n[i].z * .5f),0.5 + 0.5 * 1.5 * n[i].z);
fixed a = distance(input.uv.xy,pos);
mindis = min(mindis,a);
}
fixed e = step(abs(disc-mindis),0.04);
//实心显示
//fixed e = step(disc,mindis);
col = _Color * e;
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
下一篇文章将会实现六边形网格的绘制。