混合
混合(Blending)是计算机图形学中一项重要的技术,它决定了新渲染的像素如何与已在帧缓冲区中的像素结合。通过混合,我们可以实现透明效果、粒子系统、柔和的光照叠加以及各种特殊视觉效果。本章将深入探讨Direct3D中的混合机制、各种混合技术及其应用。
10.1 混合方程
混合操作的核心是混合方程,它定义了源像素(当前正在渲染的像素)和目标像素(帧缓冲区中已有的像素)如何组合。
10.1.1 基本混合方程
Direct3D使用以下混合方程来计算最终像素颜色:
Output = (Source × SourceBlendFactor) ⊕ (Destination × DestinationBlendFactor)
其中:
- Source: 正在渲染的像素颜色
- Destination: 帧缓冲区中已存在的像素颜色
- SourceBlendFactor: 源混合因子
- DestinationBlendFactor: 目标混合因子
- ⊕: 混合运算符(通常为加法、减法或取最小/最大值)
这个方程分别应用于RGB(颜色)通道和Alpha(透明度)通道。
10.1.2 单独的Alpha混合
Direct3D允许为RGB通道和Alpha通道定义不同的混合因子和操作:
OutputRGB = (SourceRGB × SourceBlendFactorRGB) ⊕RGB (DestinationRGB × DestinationBlendFactorRGB)
OutputA = (SourceA × SourceBlendFactorA) ⊕A (DestinationA × DestinationBlendFactorA)
这种分离允许更精细的控制混合行为,特别是在处理透明度时。
10.2 混合运算
混合运算符(Blend Operation)定义了如何组合经过因子调整后的源像素和目标像素。
10.2.1 标准混合运算
Direct3D提供以下混合运算:
-
加法(ADD): 最常用的运算,将源和目标简单相加
Output = Source × SourceFactor + Destination × DestFactor
-
减法(SUBTRACT): 从目标减去源
Output = Destination × DestFactor - Source × SourceFactor
-
反向减法(REV_SUBTRACT): 从源减去目标
Output = Source × SourceFactor - Destination × DestFactor
-
最小值(MIN): 选择源和目标的较小值
Output = min(Source, Destination)
-
最大值(MAX): 选择源和目标的较大值
Output = max(Source, Destination)
10.2.2 在Direct3D中设置混合运算
以下代码展示了如何在Direct3D 12中配置混合运算:
cpp
// 创建混合描述
D3D12_BLEND_DESC blendDesc = CD3DX12_BLEND_DESC(D3D12_DEFAULT);
// 启用第一个渲染目标的混合
blendDesc.RenderTarget[0].BlendEnable = TRUE;
// 设置RGB通道的混合运算
blendDesc.RenderTarget[0].BlendOp = D3D12_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlend = D3D12_BLEND_SRC_ALPHA;
blendDesc.RenderTarget[0].DestBlend = D3D12_BLEND_INV_SRC_ALPHA;
// 设置Alpha通道的混合运算
blendDesc.RenderTarget[0].BlendOpAlpha = D3D12_BLEND_OP_ADD;
blendDesc.RenderTarget[0].SrcBlendAlpha = D3D12_BLEND_ONE;
blendDesc.RenderTarget[0].DestBlendAlpha = D3D12_BLEND_ZERO;
// 启用所有颜色通道的写入
blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D12_COLOR_WRITE_ENABLE_ALL;
在HLSL中,我们可以通过返回带alpha值的颜色来参与混合:
hlsl
float4 PS(PixelInput input) : SV_TARGET
{
// 计算基础颜色
float4 color = baseTexture.Sample(sampler, input.texCoord);
// 设置alpha值(透明度)
color.a = 0.5f; // 50% 透明度
return color;
}
10.3 混合因子
混合因子(Blend Factor)决定了源像素和目标像素对最终输出的贡献程度。选择合适的混合因子是实现各种视觉效果的关键。
10.3.1 常用混合因子
Direct3D提供多种预定义的混合因子:
混合因子 | 描述 | 值 |
---|---|---|
D3D12_BLEND_ZERO | 乘以0 | (0, 0, 0, 0) |
D3D12_BLEND_ONE | 乘以1 | (1, 1, 1, 1) |
D3D12_BLEND_SRC_COLOR | 乘以源颜色 | (Rs, Gs, Bs, As) |
D3D12_BLEND_INV_SRC_COLOR | 乘以源颜色的补 | (1-Rs, 1-Gs, 1-Bs, 1-As) |
D3D12_BLEND_SRC_ALPHA | 乘以源Alpha | (As, As, As, As) |
D3D12_BLEND_INV_SRC_ALPHA | 乘以源Alpha的补 | (1-As, 1-As, 1-As, 1-As) |
D3D12_BLEND_DEST_COLOR | 乘以目标颜色 | (Rd, Gd, Bd, Ad) |
D3D12_BLEND_INV_DEST_COLOR | 乘以目标颜色的补 | (1-Rd, 1-Gd, 1-Bd, 1-Ad) |
D3D12_BLEND_DEST_ALPHA | 乘以目标Alpha | (Ad, Ad, Ad, Ad) |
D3D12_BLEND_INV_DEST_ALPHA | 乘以目标Alpha的补 | (1-Ad, 1-Ad, 1-Ad, 1-Ad) |
D3D12_BLEND_BLEND_FACTOR | 乘以常量混合因子 | (Rf, Gf, Bf, Af) |
D3D12_BLEND_INV_BLEND_FACTOR | 乘以常量混合因子的补 | (1-Rf, 1-Gf, 1-Bf, 1-Af) |
10.3.2 常见混合因子组合
某些混合因子组合通常一起使用来实现特定效果:
-
标准Alpha混合:
SrcBlend = D3D12_BLEND_SRC_ALPHA DestBlend = D3D12_BLEND_INV_SRC_ALPHA BlendOp = D3D12_BLEND_OP_ADD
实现传统的透明效果,最终输出 = 源 × 源Alpha + 目标 × (1 - 源Alpha)
-
加性混合:
SrcBlend = D3D12_BLEND_ONE DestBlend = D3D12_BLEND_ONE BlendOp = D3D12_BLEND_OP_ADD
简单相加源和目标,适用于光照效果、粒子发光等
-
乘法混合:
<