Blending
is used to make transparent objects.html
When graphics are rendered, after all Shaders have executed and all Textures have been applied, the pixels are written to the screen. How they are combined with what is already there is controlled by the Blend command.git
上面这段话是 Unity 官方对 Blend
命令的解释,意思大体是“ Blend
命令控制与已经存在在 GBuffer
缓存中的像素进行组合渲染(是应该渲染 GBuffer
中的像素?仍是原游戏物体的像素?仍是说两个像素作一些组合操做再渲染?)。”github
Blend Off
:关闭混合(这是默认值)。Blend SrcFactor DstFactor
:配置并启用混合。生成的颜色乘以 SrcFactor
。屏幕上已有的颜色乘以 DstFactor
,二者相加。Blend SrcFactor DstFactor, SrcFactorA DstFactorA
:与上面相同,但使用不一样的因子来混合 alpha
通道。BlendOp Op
:不要将混合颜色添加到一块儿,而是对它们执行不一样的操做。BlendOp OpColor, OpAlpha
:与上面相同,但对颜色(RGB)
和 alpha(A)
通道使用不一样的混合操做。往 SrcFactor
/SrcFactorA
和 DstFactor
/DstFactorA
上填的值。缓存
One
:混合因子 1,表示彻底的源颜色或目标颜色。Zero
:混合因子 0,舍弃掉源颜色或目标颜色。SrcColor
:源颜色值SrcAlpha
:源透明度DstColor
:目标颜色值DstAlpha
:目标透明度OneMinusSrcColor
:1 - SrcColor
OneMinusSrcAlpha
:1 - SrcAlpha
OneMinusDstColor
:1 - DstColor
OneMinusDstAlpha
:1 - DstAlpha
Add
:加法 FinalColor = SrcFactor * SrcColor + DstFactor * DstColor
Sub
:减法(源-目标) FinalColor = SrcFactor * SrcColor - DstFactor * DstColor
RevSub
:减法(目标-源) FinalColor = DstFactor * DstColor - SrcFactor * SrcColor
Min
:较小值(逐个通道比较)Max
:较大值(逐个通道比较)下面是一些目前仅限 DX11.1
支持的逻辑运算混合操做。app
⚠️ 注意:s == SrcFactor
,d == DstFactor
oop
LogicalClear
:Clear (0)LogicalSet
:Set (1)LogicalCopy
:Copy (s)LogicalCopyInverted
:Copy inverted (!s)LogicalNoop
:Noop (d)LogicalInvert
:Invert (!d)LogicalAnd
:And (s & d)LogicalNand
:Nand !(s & d)LogicalOr
:Or (s | d)LogicalNor
:Nor !(s | d)LogicalXor
:Xor (s ^ d)LogicalEquiv
:Equivalence !(s ^ d)LogicalAndReverse
:Reverse And (s & !d)LogicalAndInverted
:Inverted And (!s & d)LogicalOrReverse
:Reverse Or (s | !d)LogicalOrInverted
:Inverted Or (!s | d)当使用 Blend
时,最终颜色被计算为 result = fragment_color * SrcFactor + pixel_color * DstFactor
,这个 fragment_color
便是通过处理的片断颜色,也就是 fragment
返回的结果,pixel_color
是本来存在于缓冲区(GBuffer)
的颜色,这个 result
颜色被从新写入缓冲区,等待被其余片断 Blend
或者变成最终颜色(若是没有被其余 Blend
)。ui
上面这段话是对 语法
中的spa
Blend SrcFactor DstFactor:配置并启用混合。生成的颜色乘以 SrcFactor。屏幕上已有的颜色乘以 DstFactor,二者相加。
翻译
的分析,其中的 生成的颜色
是指 fragment
返回的结果,屏幕上已有的颜色
对应上面的 pixel_color
是指 本来存在于缓冲区(GBuffer)
的颜色 。3d
除去 Blend
参数,上述公式中的加号也是能够配置的,这个就是 BlendOp
。
上图为无任何 Blend
命令的状况下 ,左边为 Scene
视图,右边为 Game
视图。
前提条件:
Tags
为 { "RenderType"="Transprant" "Queue" = "Transparent" }
Tags
为 { "RenderType"="Transprant" "Queue" = "Transparent+100" }
,Queue
使用 Transprant
保证了 立方体
在 Game
视图中不为黑色,白色球体的 Queue
为 Transparent+100
保证了白色球体比立方体后渲染。⚠️ 注意:下面是修改的立方体的 Shader :
Blend One One
:立方体材质的像素和 GBuffer
(天空盒)中的像素混合渲染。
Blend One Zero
:只渲染立方体材质的像素。
Blend Zero One
:只渲染 GBuffer
(天空盒)中的像素。
Blend SrcAlpha OneMinusSrcAlpha
:传统透明度
Blend SrcColor zero
:只显示立方体材质的源颜色
Blend SrcColor One
:混合立方体材质的源颜色和 GBuffer
(天空盒)的源颜色
更多的组合请自行去尝试。
下面将经过风宇冲博客中的几个具体的数值计算的小例子来加深理解,以 Blend SrcAlpha OneMinusSrcAlpha
为 🌰 :
翻译成中文就是 最终颜色 = 源颜色 * 源透明值 + 目标颜色 * (1 - 源透明值)
。
假设贴图有一个不透明红色点 ● Color(1, 0, 0, 1)
,该点背景色为不透明蓝色 ● Color(0, 0, 1, 1)
。
最终颜色 = (1, 0, 0) * 1 + (0, 0, 1) * (1 - 1) = (1, 0, 0)
●
结论一:贴图 alpha 值为 1 时,仅显示贴图,不显示背景。
假设贴图有一个透明红色点 ● Color(1, 0, 0, 0)
,该点背景色为透明,但 B
通道值为 1,即 Color(0, 0, 1, 0)
。
最终颜色 = (1, 0, 0) * 0 + (0, 0, 1) * (1 - 0) = (0, 0, 1)
●
结论二:贴图 alpha 值为 0 时,仅显示混合目标即背景,不显示贴图。
可是目标 alpha 值为 0,即其实这个点的背景是透明的,而咱们却把它显示出来了,这就不对了。
经验:带 A 通道的贴图中,不仅 A 值为 0,RGB 值也要为 0,否则容易出错。
假设贴图有一个半透明红色点 ● Color(1, 0, 0, 0.8)
,该点背景色为不透明蓝色 ● Color(0, 0, 1, 1)
。
最终颜色 = (1, 0, 0) * 0.8 + (0, 0, 1) * (1 - 0.8) = (0.8, 0, 0.2)
●
而假如 0.8 变为 0.2 时,
最终颜色 = (1, 0, 0) * 0.2 + (0, 0, 1) * (1 - 0.2) = (0.2, 0, 0.8)
●
结论:贴图 alpha 值越大,颜色越偏向贴图;alpha 值越小,颜色越偏向混合目标。
参考文章:
若有内容有误,欢迎 issue 指正。
转载请注明出处!