1.如果Shader代码内,没有写到Blend,那么模式Blend Off 是不进行混合的。
下面测试一下Blend的各种模式,先交代一下各个参数代表的含义
SrcColor 要渲染的颜色,比如某张贴图进行绘制的时候,该贴图就是要渲染的颜色SrcColor
SrcAlpha 要渲染的透明度,同上
DstColor 已经渲染到屏幕上的颜色
DstAlpha 已经渲染到屏幕上的颜色透明度
One MinusSrcColor 1-要渲染的颜色
One MinusSrcAlpha 1-要渲染 透明度
One MiusDstColor 1-屏幕上显示的颜色
One MinusDstAlpha 1-屏幕上显示颜色的alpha
看一下各种参数效果。两张素材图:一张不透明的背景图,一张四角透明的icon图
Blend Off 关闭混合,效果如下
很明显,四角透明并没有显示出底图来。
(1)现在想要一个简单的混合,只描述这个Icon,不透明的部分,就是显示icon内容,透明的部分显示背景图。
公式如下:
Blend SrcAlpha OneMiusSrcAlpha 这个实际算法是:SrcColorSrcAlpha + (1-SrcAlpha)DstColor
(2)Blend One One 源色+目标色 正常的叠加,效果会比之前的亮,毕竟rgb 都增加了
(3)Blend SrcAlpha One 源色*源Alpha + 目标色,这个效果跟 (2)效果很近,都会增亮
这个没有白色区域,是因为 源色源Alpha
(4)Blend OneMinusSrcAlpha One (1-源Alpha)源色 + 目标色
很明显,源色透明区域显示了白色,非透明区域显示了背景色
(5)Blend OneMinusDstAlpha One (1-DstAlpha)SrcColor + DstColor
(6)Blend DstColor Zero DstColorSrcColor + 0DstColor
(7)Blend OneMinusDstColor Zero (1-DstColor)SrcColor + 0DstColor
效果是,源色透明的区域有了点背景的样子
(8)Blend Zero SrcAlpha 0源色 + 源Alpha目标色
具体的效果,需要根据公式推算一下,甚至是 尝试一下。
附代码:
Shader "Blend/BlendTest"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Transparent" }
//不写Blend的时候也是默认Blend Off 只显示源色,不会混合上Gbuff上的色素。(目前测试的是透明部分显示了白色)
//Blend Off
//(1)公式: 源色*源Alpha + (1-源Alpha)*目标色
//Blend SrcAlpha OneMinusSrcAlpha
//(2)效果是:叠加,颜色会比之前亮 。叠加的时候会不会考虑Alpha ?
//Blend One One
//(3)得到的图案是背景图正常,透明区域正常显示背景,非透明区域变亮了
//Blend SrcAlpha One
//(4)公式:(1-源Alpha)*源色 + 目标色 :效果是 源色透明区域显示白色,不透明区域显示背景
//Blend OneMinusSrcAlpha One
//(5)公式:(1-DstAlpha)*SrcColor + DstColor :效果是源色没有显示出来,因为背景是不透明的
//Blend OneMinusDstAlpha One
//(6)DstColor*SrcColor + 0*DstColor
//Blend DstColor Zero
//(7)(1-DstColor)*SrcColor + 0*DstColor :效果是透明区域,有了点背景的样子
//Blend OneMinusDstColor Zero
Blend Zero SrcAlpha
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
//用下面的方法取uv ,是为了让uv 受tilng 跟offset 影响
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
fixed4 col = tex2D(_MainTex, i.uv);
return col;
}
ENDCG
}
}
}