学习教程来自:【技术美术百人计划】图形 3.2 混合模式及剔除

笔记

1. 什么是混合模式?

将当前已有颜色和即将绘制的颜色混合在一起的方式或算法。
语法:
|代码|说明|
|:——:|:——:|
|Blend Off|关闭混合(默认)|
|Blend SrcFactor DstFactor|color = shader输出颜色 * SrcFactor op GBuffer中的颜色 * DstFactor|
|Blend SrcFactor DstFactor, SrcFactorA DstFactorA|同上,额外指定了Alpha通道的混合参数|
|BlendOp Value|指定混合方式,默认ADD|
|BlendOp OpColor, OpAlpha|同上,额外指定了Alpha|
|AlphaToMaskOn|常用在开启MSAA的地表植被的渲染|

2. 混合模式有哪些类型?

一些常见的混合,详见官方文档

Blend SrcAlpha OneMinusSrcAlpha // Traditional transparency alpha混合
Blend One OneMinusSrcAlpha // Premultiplied transparency 预乘透明度
Blend One One // Additive 相加混合
Blend OneMinusDstColor One // Soft Additive 柔和相加混合
Blend DstColor Zero // Multiplicative 相乘混合 正片叠底
Blend DstColor SrcColor // 2x Multiplicative 2倍相乘混合

使用代码

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

3. 混合模式的实现方式

src当前颜色,dst缓冲区已有颜色,一些效果暂时调不出来(BlendOp为空的部分)

混合模式 PS代码 BlendOp SrcBlend DstBlend 备注
Alphablend Src.a Src + (1.0 - Src.a) Dst ADD SrcAlpha OneMinusSrcAlpha 透明混合
Darken min(Src, Dst) Min - - 变暗
Multiply Src * Dst Multiply - - 正片叠底
ColorBurn 1.0 - (1.0 - Dst) / Src ColorBurn - - 颜色加深
LinearBurn Src + Dst - 1.0 - - - 线性加深
DarkerColor (Src.x + Src.y + Src.z < Dst.x + Dst.y + Dst.z) ? Src : Dst Min - - 深色
Lighten max(Src, Dst) Max - - 变亮
Screen Src (1 - Dst) + Dst 1 ADD OneMinusDstColor One 滤色
ColorDodge Dst / (1.0 - Src) ColorDodge - - 颜色减淡
LinearDodge Src + Dst ADD One One 线性减淡
LighterColor (Src.x + Src.y + Src.z > Dst.x + Dst.y + Dst.z) ? Src : Dst Lighten - - 浅色
Overlay (Dst < 0.5) ? 2.0 Src Dst : 1.0 - 2.0 (1.0 - Src) (1.0 - Dst) Overlay - - 叠加
SoftLight (Src < 0.5) ? Dst - (1.0 - 2.0 Src) Dst (1.0 - Dst)
: (Dst < 0.25) ? Dst 000000+ (2.0
Src - 1.0) Dst ((16.0 Dst - 12.0) Dst + 3.0)
: Dst + (2.0 Src - 1.0) (sqrt(Dst) - Dst)
SoftLight - - 柔光
HardLight (Src < 0.5) ? 2.0 Src Dst : 1.0 - 2.0 (1.0 - Src) (1.0 - Dst) HardLight - - 强光
VividLight (Src < 0.5) ? 1.0 - (1.0 - Dst) / (2.0 Src) : Dst / (2.0 (1.0 - Src)) - - - 亮光
LinearLight 2.0 * Src + Dst - 1.0 - - - 线性光
PinLight (2.0 Src - 1.0 > Dst) ? 2.0 Src - 1.0 : (Src < 0.5 Dst) ? 2.0 Src : Dst - - - 点光
HardMix floor(Src + Dst) - - - 实色混合
Difference abs(Dst - Src) Difference - - 差值
Exclusion Src + Dst - 2.0 Src Dst Exclusion - - 排除
Subtract Src - Dst ReverseSubstrat One One 减去
Divide Src / Dst - - - 划分
Hue Dst = RGB2HSV(Dst);Dst.x = RGB2HSV(Src).x; return HSV2RGB(Dst); HSLHue - - 色相
Saturation Dst = RGB2HSV(Dst); Dst.y = RGB2HSV(Src).y; return HSV2RGB(Dst); - - - 饱和度
Color Src = RGB2HSV(Src);Src.z = RGB2HSV(Dst).z; return HSV2RGB(Src); - - - 颜色
Luminosity float dLum = dot(Dst, float3(0.3, 0.59, 0.11));
float sLum = dot(Src, float3(0.3, 0.59, 0.11));
float lum = sLum - dLum;
float3 C = Dst + lum;
float minC = min(min(C.x, C.y), C.z);
float maxC = max(max(C.x, C.y), C.z);
if (minC < 0.0)
    return sLum + ((C - sLum) sLum) / (sLum - minC);
else if (maxC > 1.0)
    return sLum + ((C - sLum)
(1.0 - sLum)) / (maxC - sLum);
else
    return C;
HSLLuminoslingity - - 明度

ColorBurn只支持OpenGL,DX不支持

遇到的问题:源码中的部分混合效果需要颠倒src和dst的位置。OpenGL下部分效果可以调出,但自带的枚举下SrcBlend和DstBlend失效

4. 剔除的实现方式

  1. 法线剔除:根据法线朝向进行剔除,Cull Off/Front/Back
  2. 面裁切:在片元阶段直接丢弃满足某些条件的像素,Clip(),在某些PowerVR机型上效率很低,最好在AlphaTest队列中使用

作业

实现常用的混合模式,并设计使用界面

基于3中的表格,增加了混合的配置界面,对于src和dst可调的开放了参数设置,并增加了预设值。对于失效的则不显示参数选择。正确性未知的不予显示。