Unity Shader - ShaderLab: Blending 混合

目录:Unity Shader - 知识点目录(先占位,后续持续更新)
原文:ShaderLab: Blending
版本:2019.1

ShaderLab: Blending

混合

(如果大家看完还是看不懂可以再去查看我之前写过的一篇译文:Vulkan - Color Blending

混合用于透明对象
在这里插入图片描述
当所有Shader都执行了,并且所有纹理都被应用了,对象的像素写入到了屏幕,那么图形被渲染出来了。如何将它们与已经存在的内容组合在一起是由Blend命令控制的。

Syntax

语法

Blend Off:关闭混合(这是默认的)

Blend SrcFactor DstFactor:配置开启的混合方式。片段生成的颜色将乘以 SrcFactor。已经在屏幕了的颜色(准确说应该是已经存在framebuffer中的颜色,可查看我之前写的译文:Vulkan - Color Blending)乘以 DstFactor,然后将他们的积相加,组合为新的颜色。

(这里吐槽一下,翻译这么多篇Unity文档了,觉得Unity描述、说明得相当烂,还是OpenGL,或是Direct或是Vulkan说的最清楚,反正后面我会不定期吐槽,但是要用Unity开发啊,所以还是了解清楚好一些)

Blend SrcFactor DstFactor, SrcFactorA DstFactorA:和上面一样,但使用了不一样的alpha通道混合因子。

BlendOp Op:就如上面说的ColorBlend的积后,再相加的操作,也可以设置不一样的操作。

BlendOp OpColor, OpAlpha:和上面一样,但使用了不一样的颜色(RGB)和透明(A)通道的混合。


注意上面官方没有说明一些Blend分类:
混合可简写成:
finalColor.rgb = SrcColor.rgb * SrcFactor <ColorOp> DstColor.rgb * DstFactor;
finalColor.a = SrcAlpha * SrcFactorA <AlphaOp> DstAlpha * DstFactorA;
属于ColorBlend的是:SrcFactor,DstFactor
属于AlphaBlend的是:SrcFactorA,DstFactorA
属于OpBlend的是:ColorOp,AlphaOp
可查看我之前写的译文:Vulkan - Color Blending

另外,你还可以给指定渲染目标时设置混合模式。当你使用multiple render target(MRT:多渲染目标)渲染时,可以给每个渲染目标像上面一样设置混合模式。下面的语法可以给每个单独的渲染目标设置混合模式,N 就是渲染目标的索引(0到7)。这个功能工作于现代应将(APIs/GPUs(DX11/12, GLCore, Meta, PS4)):

  • Blend N SrcFactor DstFactor
  • Blend N SrcFactor DstFactor, SrcFactorA DstFactorA
  • BlendOp N Op
  • BlendOp N OpColor, OpAlpha

AlphaToMask On:开启alpha-to-coverage覆盖。当使用MSAA(Multi-Sample Anti-Aliasing多重采样抗锯齿),alpha-to-coverage修改多重采样的覆盖掩码按比例地控制像素着色器的alpha值结果。这通常用于alpha测试后锯齿比较少的轮廓的情况;用在植被或是其他的alpha测试的shader上比较有用。

Blend operations

混合操作

下面是用于混合操作的枚举:

枚举描述
Add将source与destination相加。
SubSource - Destination
RevSubDestination-Source
MinMin(Source, Destination
MaxMax(Source, Destination
LogicalClear逻辑操作:Clear(0) 仅DX11.1
LogicalSet逻辑操作:Set(1) 仅DX11.1
LogicalCopy逻辑操作:Copy(s) 仅DX11.1
LogicalCopyInverted逻辑操作:Copy反向值(!s) 仅DX11.1
LogicalNoop逻辑操作:Noop(d) 仅DX11.1 (空操作)
LogicalInvert逻辑操作:Invert(!d) 仅DX11.1
LogicalAnd逻辑操作:And(s&d) 仅DX11.1
LogicalOrOr(s | d) 仅DX11.1
LogicalNorNor !(s | d) 仅DX11.1
LogicalXorXor (s ^ d) 仅DX11.1
LogcialEquivEquivalence !(s^d) 仅DX11.1
LogicAndReverseReverse And (s & !d) 仅DX11.1
LogicalAndInvertedInverted And (!s & d) 仅DX11.1
LogicalOrReverseReverse Or (s | !d) 仅DX11.1
LogicalOrInvertedInverted Or (!s | d) 仅DX11.1

Blend factors

混合因子

下面的枚举都是混合命令中两个因子 SrcFactor 和 DstFactor的值。Sourface 是片段计算的颜色, Destination 是存在于屏幕的颜色(准确说是:framebuffer的颜色)。混合因子不会收 BlendOp 的逻辑操作影响,因为BlendOp是再因子应用了Src和Dst后的逻辑处理,对最终颜色计算值会有影响。

枚举描述
One(1,1,1)的分享值,可用于Src或Dst
Zero(0,0,0)
SrcColor(SrcColor.rgb)
SrcAlpha(SrcAlpha.aaa)
DstColor(DstColor.rgb)
DstAlpha(SrcAlpha.aaa)
OneMinusSrcColor(1 - SrcColor.rgb)
OneMinusSrcAlpha(1 - SrcColor.aaa)
OneMinusDstColor(1 - DstColor.rgb)
OneMinusDstAlpha(1 - DstColor.aaa)

Details

下面是常用的混合类型:

Blend SrcAlpha OneMinusSrcAlpha // 传统透明
Blend One OneMinusSrcAlpha // 预乘Alpha的透明
Blend One One // 叠加
Blend OneMinusDstColor One //  软叠加
Blend DstColor Zero // 混合色调
Blend DstColor SrcColor // 双倍的混合色调

Alpha blending, alpha testing, alpha-to-coverage

alpha混合,alpha测试,alpha覆盖

绘制多数的不透明或全透明对象时,当透明度是使用纹理的alpha通道来决定的(如,叶子,草,锁链,等等),一些常用的用法如下:

Alpha blending

alpha混合
Regular alpha blending
一般的alpha混合

通常是意味着对象被认为是"semitransparent"(半透明的),因此不能使用某些渲染功能(例如:延迟渲染,不能接收阴影)。凹面体或是自身重叠了alpha混合的对象通常也有绘制顺序的问题。

通常,alpha混合着色器也会设置 transparent的render queue渲染队列,且会关闭深度写入。就像下面的代码写法一样:

// inside SubShader
Tags { "Queue"="Transparent" "RenderType"="Transparent" "IgnoreProjector"="True" }

// inside Pass
ZWrite Off
Blend SrcAlpha OneMinusSrcAlpha

Alpha testing/cutout

alpha测试/剔除
clip() in pixel Shader
在像素着色器中的clip()

在像素着色器中使用 clip() HLSL的指令,那么这个像素将被取消掉绘制(当clip(v)中的v值有小于0的数值时都会被取消绘制该像素,其实v可以是Type[N], N:1~4都分量维度数,如:float, half, fixed1, float3, half4,那么如果所有的分量都小于0,那么就会剔除该像素的绘制)。这意味着,对象仍然还是不透明对象,并且也不会有渲染顺序的问题。然而,这意味着像素只能是要么不透明,要么全透明,那么将导致锯齿的出现(“jaggies”)。

通常,alpha测试的Shader也会设置 cutout(AlphaTest) 的render queue 渲染队列,如下代码:

// inside SubShader
Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" "IgnoreProjector"="True" }

// inside CGPROGRAM in the fragment Shader:
clip(textureColor.a - alphaCutoffValue);

Alpha-to-coverage

alpha覆盖
AlphaToMask On, at 4xMSAA
在4被MSAA(多重采样)开启AlphaToMask

当使用多重采样来抗锯齿(MSAA,查看 QualitySettings),使用GPU的alpha-to-coverage功能,可能会提升alpha测试这种方法的效果。提升了边缘的表现,依赖于MSAA的使用级别。

这个功能在纹理几乎都不透明或是全透明的情况下工作得最大,并且看想来会有部分的半透明似的效果(草,叶子,之类的非常适合)。

通常,alpha-to-coverage Shader 也会是指 render queue 渲染队列。代码如下:

// inside SubShader
Tags { "Queue"="AlphaTest" "RenderType"="TransparentCutout" "IgnoreProjector"="True" }

// inside Pass
AlphaToMask On

Example

这儿有个例子,将纹理叠加到屏幕颜色重:

Shader "Simple Additive" {
    Properties {
        _MainTex ("Texture to blend", 2D) = "black" {}
    }
    SubShader {
        Tags { "Queue" = "Transparent" }
        Pass {
            Blend One One
            SetTexture [_MainTex] { combine texture }
        }
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值