概括:
著色流程
看上圖,會發現 Blending 發生在著色流程的最后。片段著色,
Alptha Test
完成后,如何和 ColorBuffer
中已有顏色混合,就是 Bland
指令需要做的事情。
應用:
Blend 指令可以在 Pass
內部,用來決定這一個 Pass
的渲染狀態;也可以放在 SubShader
,用來決定其所有 Pass 的渲染狀態。
Blending 方程式為:
finalValue = sourceFactor * sourceValue operation destinationFactor * destinationValue
方程式中各變量的含義:
finalValue
is the value that the GPU writes to the destination buffer.
GPU 寫進目標緩存的值sourceFactor
is defined in the Blend command.
由 Blend 指令定義sourceValue
is the value output by the fragment shader.
片段著色器輸出的值-
operation
is the blending operation.
Blend 操作,可用的指令有:值 含義 Add buffer_value
+片段著色器輸出值
Sub 片段著色器輸出值
-buffer_value
RevSub buffer_value
-片段著色器輸出值
Min Math.Min( 片段著色器輸出值
,buffer_value
)Max Math.Max( 片段著色器輸出值
,buffer_value
) destinationFactor
is defined in the Blend command.
由 Blend 指令定義destinationValue
is the value already in the desination buffer.
目標緩存中已經存在的值
定義 | 樣例 | 描述 |
---|---|---|
Blend <state> |
Blend Off |
關閉 Blend ,這是默認設置 |
Blend <render target> <state> |
Blend 1 Off |
同上,但是給定了渲染目標 |
Blend <source factor> <destination factor> |
Blend One Zero |
為默認渲染目標開啟Blend |
Blend <render target> <source factor><destination factor> |
Blend 1 One Zero |
同上,但是指定了渲染目標 |
Blend <source factor RGB> <destination factor RGB>, <source factor alpha> <destination factor alpha> |
Blend One Zero,Zero One |
為默認渲染目標開啟Blend,為 RGB 和 alpha 值設置單獨的混合因子 |
Blend <render target> <source factor RGB> <destination factor RGB>, <source factor alpha> <destination factor alpha> |
Blend 1 One Zero,Zero One | 同上,但給定了渲染目標 |
參數可能的值:
名稱 | 值 | 含義 |
---|---|---|
render target | int[0-7] | 渲染目標編號,從0到7 |
state | Off |
關閉 blending |
factor | One |
輸入值1,相當于直接用源值或者目標值代入公式 |
Zero |
輸入值0,相當于移除源值或者目標值 | |
SrcColor |
GPU 用此輸入值乘源值 | |
DestColor |
GPU 將此輸入的值乘以目標值(color buffer中的值) | |
OneMinusSrcColor |
GPU 將此輸入值乘以(1 - 源值) | |
OneMinusSrcAlpha |
GPU 將此輸入值乘以(1 - 源值的Alpha) | |
OneMinusDstColor |
GPU 將此輸入值乘以(1 - 目標值) | |
OneMinusDstAlpha |
GPU 將此輸入值乘以(1 - 目標的Alpha) |
注釋
- 源值:片段著色器輸出的值
- 目標值:color buffer 中的當前值
常見的混合類型:
-
Blend SrcAlpha OneMinusSrcAlpha
// 傳統的透明度
傳統的透明度 -
Blend One OneMinusSrcAlpha
// 預乘透明度
預乘透明度 -
Blend One One
// 疊加
疊加 -
Blend OneMinusDstColor One
// 柔性疊加
柔性疊加 -
Blend DstColor Zero
// 乘
Blend DstColor Zero -
Blend DstColor SrcColor
// 加倍乘
Blend DstColor SrcColor
測試用的Shader
Shader "Unlit/TestBlendShader"
{
Properties
{
_Color ("Main Color", Color) = (1,1,1,1)
[Header(Blending)]
// https://docs.unity3d.com/ScriptReference/Rendering.BlendMode.html
[Enum(UnityEngine.Rendering.BlendMode)]_DecalSrcBlend("_DecalSrcBlend (default = SrcAlpha)", Int) = 5 // 5 = SrcAlpha
[Enum(UnityEngine.Rendering.BlendMode)]_DecalDstBlend("_DecalDstBlend (default = OneMinusSrcAlpha)", Int) = 10 // 10 = OneMinusSrcAlpha
}
SubShader
{
Tags { "RenderType"="Opaque" }
Blend[_DecalSrcBlend][_DecalDstBlend]
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 normal : NORMAL;
};
struct v2f
{
float2 wnormal : NORMAL;
float4 vertex : SV_POSITION;
};
fixed4 _Color;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.wnormal = UnityObjectToWorldNormal((v.normal,1));
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return _Color * (dot(normalize(_WorldSpaceLightPos0.xyz),i.wnormal) * 0.5 + 0.5);
}
ENDCG
}
}
}