|
一、前言
这篇文章内容包括:
- 对于Unity 官方Default UI模板 的注释
- 自定义 UI shader 模板
这是我整理通用Unity UI shader 系列的文章之一,因为最近比较忙没有时间搭博客,内容会先更新在知乎上。
参考:
二、Unity Default UI 模板
UIShader因为要让图片渲染跟rectTransform组件相匹配,所以一般的shader无法直接用在UI上 2.1 Properties
Properties
{
[PerRendererData] _MainTex ("Sprite Texture", 2D) = "white" {}
_StencilComp ("Stencil Comparison", Float) = 8
_Stencil ("Stencil ID", Float) = 0
_StencilOp ("Stencil Operation", Float) = 0
_StencilWriteMask ("Stencil Write Mask", Float) = 255
_StencilReadMask ("Stencil Read Mask", Float) = 255
_ColorMask ("Color Mask", Float) = 15
[Toggle(UNITY_UI_ALPHACLIP)] _UseUIAlphaClip ("Use Alpha Clip", Float) = 0
}
[PerRendererData] :此属性的纹理值将以MaterialPropertyBlock的形式从渲染器数据中获取,即unity会自动将 UI的Image Component的Source Image传入。(似乎可以用于批处理,提高性能)。
_Stencil:模板测试相关属性,Unity会自动修改参数,UI可以使用模板测试进行不显示,比如Mask。
_ColorMask:设置颜色通道写入遮罩。写入 ColorMask 0 可关闭对所有颜色通道的渲染。默认模式是 写入所有通道 (RGBA),但是对于某些特殊效果,希望不修改某些通道,或完全禁用颜色写入。
_UseUIAlphaClip是 是否用clip来进行不显示 。[Toggle(UNITY_UI_ALPHACLIP)], 如果Toggle是true , 则自动#define UNITY_UI_ALPHACLIP ,可以用#ifdef进行预处理。
2.2 SubShader
UIShader是AB(alpha blend)类型的shader,跟透明混合一样,在subshader中需要设置特殊变量,并且关闭深度写入 SubShader
{
Tags
{
"Queue"="Transparent" // UI存在透明图片,所以渲染队列是 Transparent
"IgnoreProjector"="True" // 忽略投影器Projector
"RenderType"="Transparent" // 渲染模式
"PreviewType"="Plane" // UI预览的正常都是一个平面(Plane)
"CanUseSpriteAtlas"="True" // UI经常使用图集,所以要设置图集可以使用
}
Stencil
{
// UI 模板测试,把在Properties中定义的模板参数导入,Unity会自动修改
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off // 剔除关闭
Lighting Off // 光照关闭
ZWrite Off // 深度写入关闭
ZTest [unity_GUIZTestMode] // 用于UI组件的shader都要包含一句:ZTest [unity_GUIZTestMode],以确保UI能在前层显示
Blend SrcAlpha OneMinusSrcAlpha // 混合模式是 OneMinusSrcAlpha 正常模式(透明度混合)
ColorMask [_ColorMask] // 将定义的_ColorMask参数导入
.....
}
三、自定义 UI Shader 模板
Shader "UI/CommonUI"
{
Properties
{
[PerRendererData] _MainTex ("Texture", 2D) = "white" {}
// 模板测试属性 和 ColorMask 一般不控制,所以在属性面板上隐藏
[HideInInspector]_StencilComp ("Stencil Comparison", Float) = 8
[HideInInspector]_Stencil ("Stencil ID", Float) = 0
[HideInInspector]_StencilOp ("Stencil Operation", Float) = 0
[HideInInspector]_StencilWriteMask ("Stencil Write Mask", Float) = 255
[HideInInspector]_StencilReadMask ("Stencil Read Mask", Float) = 255
}
SubShader
{
Tags
{
"Queue"="Transparent"
"IgnoreProjector"="True"
"RenderType"="Transparent"
"PreviewType"="Plane"
"CanUseSpriteAtlas"="True"
}
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
Cull Off
Lighting Off
ZWrite Off
ZTest [unity_GUIZTestMode]
Blend SrcAlpha OneMinusSrcAlpha
ColorMask [_ColorMask]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#pragma multi_compile _ UNITY_UI_ALPHACLIP
#include "UnityUI.cginc"
#include "UnityCG.cginc"
fixed4 _TextureSampleAdd; // Unity管理:图片格式用Alpha8
float4 _ClipRect;// Unity管理:2D剪裁使用
sampler2D _MainTex;
struct a2v{
float4 vertex : POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_INPUT_INSTANCE_ID
};
struct v2f{
float4 vertex : SV_POSITION;
float4 color : COLOR;
float2 texcoord : TEXCOORD0;
UNITY_VERTEX_OUTPUT_STEREO
};
v2f vert(a2v IN){
v2f OUT;
UNITY_SETUP_INSTANCE_ID(IN);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(OUT);// 实例化处理
OUT.vertex = UnityObjectToClipPos(IN.vertex);// 模型空间到裁剪空间
OUT.color = IN.color;
OUT.texcoord = IN.texcoord;
return OUT;
}
fixed4 frag(v2f IN):SV_Target{
// 直接读取纹理颜色 并且乘上 ImageColor
half4 color = tex2D(_MainTex,IN.texcoord) * IN.color;
return color;
}
ENDCG
}
}
} |
|