原文链接:https://docs.unity3d.com/Manual/SL-Blend.html
融合用于来构建透明物体。
(图片见原网页)
当所有图形被渲染,在所有shader被执行和所有纹理被采样之后,像素被画到屏幕上。Blend命令用来控制当那里已经有一个像素的时候,它们将如何合并。
语法
Blend Off:关掉融合(默认)。
Blend SrcFactor DstFactor: 配置并且启用融合。要生成的颜色乘以SrcFactor,已经在屏幕上的颜色要乘以DstFactor,并且这两者相加到一起。
Blend SrcFactor DstFactor, SrcFactorA DstFactorA:与上面一样,但是使用了不同的factor来融合alpha通道。
BlendOp Op:不使用将融合的颜色相加的方式,而执行一种不一样的操作。
BlendOp OpColor, OpAlpha: 同上面一样,但是对颜色(RGB)通道和alpha(A)通道使用不同的融合方式。
另外,你可以设置高级渲染目标融合模式。当使用多个渲染目标渲染(MRT)时,上文所述的常规语法将给所有渲染目标设置相同的融合模式。下面的语法可以为每个独立的渲染目标设置不同的渲染模式,N是渲染目标的索引(0..7)。这个功能可以用于大多数现代APIs/GPUs(DX11/12, GLCore, Metal, PS4):
·Blend N SrcFactor DstFactor
·Blend N SrcFactor DstFactor, SrcFactorA DstFactorA
·BlendOp N Op
·BlendOp N OpColor, OpAlpha
AlphaToMask On: 打开alpha-to-coverage,当使用MSAA(多重采样抗失真),alpha-to-coverage会根据像素shader的alpha结果值适当的修改多重采样覆盖遮罩。这通常比常规的alpha测试的外边框失真更少;对于植物和经过alpha测试的shader有用。
Blend运算
可以使用下面的Blend运算:
Add 将source和destination相加。
Sub 从source减去destination。
RevSub 从destination减去source。
Min 使用source和destination中更小的。
Max 使用source和destination中更大的。
LogicalClear 逻辑操作: Clear (0) DX11.1 only.
LogicalSet 逻辑操作: Set (1) DX11.1 only.
LogicalCopy 逻辑操作: Copy (s) DX11.1 only.
LogicalCopyInverted 逻辑操作: Copy inverted (!s) DX11.1 only.
LogicalNoop 逻辑操作: Noop (d) DX11.1 only.
LogicalInvert 逻辑操作: Invert (!d) DX11.1 only.
LogicalAnd 逻辑操作: And (s & d) DX11.1 only.
LogicalNand 逻辑操作: Nand !(s & d) DX11.1 only.
LogicalOr 逻辑操作: Or (s | d) DX11.1 only.
LogicalNor 逻辑操作: Nor !(s | d) DX11.1 only.
LogicalXor 逻辑操作: Xor (s ^ d) DX11.1 only.
LogicalEquiv 逻辑操作: Equivalence !(s ^ d) DX11.1 only.
LogicalAndReverse 逻辑操作: Reverse And (s & !d) DX11.1 only.
LogicalAndInverted 逻辑操作: Inverted And (!s & d) DX11.1 only.
LogicalOrReverse 逻辑操作: Reverse Or (s | !d) DX11.1 only.
LogicalOrInverted 逻辑操作: Inverted Or (!s | d) DX11.1 only.
Blend要素
下面所有的属性在Blend命令中对于SrcFactor和DstFactor都是有效的。Source指的是要计算的颜色,Destination是已经在屏幕上的颜色。如果BlendOp使用的是逻辑运算符,Blend要素会被忽略。
One 使用它将保持source或destination的完整的颜色。
Zero 使用它将移除source或destination的值。
SrcColor 使用它将乘以source颜色值。
SrcAlpha 使用它将乘以source的alpha值。
DstColor 使用它将乘以frame buffer中的source颜色值。
DstAlpha 使用它将乘以frame buffer中的source的alpha值。
OneMinusSrcColor 使用它将乘以(1-source颜色值)。
OneMinusSrcAlpha 使用它将乘以(1-source的alpha值)。
OneMinusDstColor 使用它将乘以 (1 - destination颜色值)。
OneMinusDstAlpha 使用它将乘以 (1 - destination的alpha值)。
细节
下面是最常用的融合模式:
Blend SrcAlpha OneMinusSrcAlpha // Traditional transparency
Blend One OneMinusSrcAlpha // Premultiplied transparency
Blend One One // Additive
Blend OneMinusDstColor One // Soft Additive
Blend DstColor Zero // Multiplicative
Blend DstColor SrcColor // 2x Multiplicative
alpha融合,alpha测试,alpha-to-coverage
对于绘制大多数完全不透明或者完全透明的对象,它们的透明度由其纹理的Alpha通道来定义(比如树叶、草、链条围栏等等),通常使用几种方法:
Alpha混合
(图片见原网页)
定期alpha混合
这通常意味着对象必须被视为“半透明”,因此就不能使用某些渲染功能(比如:deferred shading,不能接受阴影)。凹面或者叠加alpha融合对象通常有一些渲染顺序问题。
通常alpha融合shader要设置渲染队列为transparent,并且关闭深度写入。所以shader代码看起来像这样:
// inside SubShader
Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" }
// inside Pass
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha
Alpha测试/裁剪
(图片见原网页)
在像素shader中使用clip()
在像素shader中通过使用HLSL的clip()指令,可以基于某些标准来控制某些像素是否被丢弃。这意味着对象仍然可以被视为完全不透明的,并且没有绘制顺序问题,但是,这意味着所有像素都是完全不透明或透明的,导致锯失真(“锯齿”)。
通常,经过alpha测试过的shader也会设置裁剪渲染队列,所以shader看起来像这样:
// inside SubShader
Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" "IgnoreProjector"="True" }
// inside CGPROGRAM in the fragment Shader:
clip(textureColor.a - alphaCutoffValue);
Alpha-to-coverage
(图片见原网页)
AlphaToMask开启,4倍MSAA
当使用多重采样抗失真(MSAA,请看QualitySettings一文,链接见原网页),可以通过使用alpha-to-coverage GPU功能来改进alpha测试方法。可以根据MSAA所使用的级别,来改善边缘显示。此功能最适用于大多数不透明或透明的纹理,并且具有非常薄的“部分透明”区域(草,树叶和类似物)。
通常,alpha-to-coverage shader还会设置剪切渲染队列。所以Shader代码看起来像:
// inside SubShader
Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" "IgnoreProjector"="True" }
// inside Pass
AlphaToMask On
例子
这里有一个简单的示例shader,添加一个纹理到已经在屏幕上的任何东西上。
Shader "Simple Additive" {
Properties {
_MainTex ("Texture to blend", 2D) = "black" {}
}
SubShader {
Tags { "Queue" = "Transparent" }
Pass {
Blend One One
SetTexture [_MainTex] { combine texture }
}
}
}
网友评论