一侧纯、原理
遮罩shader的原理其實就是乘法運算
color * 1 = color
color * 0 = 0
在計算機程序語言表達顏色的時候翎冲,(1,1,1,1)表示白色和不透明簸州,(0,0,0,0)表示黑色和完全透明
比如我們將color貼圖和mask貼圖(白色背景的可能看不見缠借,可以點擊放大)相乘拆火,就會得到一個透明的彩色unity logo
color
mask
color_logo.png
二跳夭、實踐
1、準(zhǔn)備場景資源
首先我們分別新建一個表面著色器和材質(zhì)们镜,都命名為Mask币叹,將shader賦予材質(zhì)。
然后編輯shader代碼模狭,把無關(guān)的屬性和代碼都刪掉颈抚,精簡代碼如下,只留一個主貼圖屬性:
Shader "Custom/Mask" {
Properties {
_MainTex ("Albedo (RGB)", 2D) = "white" {}
}
SubShader {
Tags { "RenderType"="Opaque" }
CGPROGRAM
#pragma surface surf Standard
#pragma target 3.0
sampler2D _MainTex;
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D (_MainTex, IN.uv_MainTex);
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
我們在場景里新建一個Plane胞皱,賦上Mask材質(zhì)邪意,材質(zhì)的Albedo貼圖槽選擇color貼圖,現(xiàn)在材質(zhì)的效果應(yīng)該是這樣的:
plane.png
2反砌、增改shader代碼
Shader "Custom/Mask" {
Properties {
_MainTex("Albedo (RGB)", 2D) = "white" {}
_MaskTex("Mask", 2D) = "white" {} //add
}
SubShader {
Tags { "RenderType"="Opaque" "Queue"="Transparent"} //modified
Blend SrcAlpha OneMinusSrcAlpha //add
CGPROGRAM
#pragma surface surf Standard keepalpha //modified
#pragma target 3.0
sampler2D _MainTex;
sampler2D _MaskTex; //add
struct Input {
float2 uv_MainTex;
};
void surf (Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
fixed4 m = tex2D (_MaskTex, IN.uv_MainTex); //add
c = c * m; //add
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
這三句修改的代碼都是為了讓shader支持透明
Tags { "RenderType"="Opaque" "Queue"="Transparent"} //modified
Blend SrcAlpha OneMinusSrcAlpha //add
#pragma surface surf Standard keepalpha //modified
最后我們把mask貼圖拖進材質(zhì)新增的Mask貼圖槽
material.png
現(xiàn)在材質(zhì)效果應(yīng)該就是這樣了:
color_logo.png
三雾鬼、優(yōu)化
但是通常我們用的mask貼圖都不是透明貼圖,而是黑白貼圖宴树。這是因為帶透明通道的貼圖消耗更高策菜,而只要我們稍微改一下代碼,黑白mask貼圖可以實現(xiàn)和透明mask貼圖完全一樣的效果酒贬。
我們再將shader代碼修改如下又憨,僅需改一處代碼:
Shader "Custom/Mask" {
Properties{
_MainTex("Albedo (RGB)", 2D) = "white" {}
_MaskTex("Mask", 2D) = "white" {}
}
SubShader{
Tags { "RenderType" = "Opaque" "Queue" = "Transparent"}
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma surface surf Standard keepalpha
#pragma target 3.0
sampler2D _MainTex;
sampler2D _MaskTex;
struct Input {
float2 uv_MainTex;
};
void surf(Input IN, inout SurfaceOutputStandard o) {
fixed4 c = tex2D(_MainTex, IN.uv_MainTex);
fixed4 m = tex2D(_MaskTex, IN.uv_MainTex);
c = c * m.r; //modified
o.Albedo = c.rgb;
o.Alpha = c.a;
}
ENDCG
}
FallBack "Diffuse"
}
mask_black.png
然后我們再把透明mask貼圖換成黑白的mask貼圖,可以得到同樣的遮罩效果锭吨。