alpha混合原理(2)
alpha混合原理
在前面介绍的示例程序中,绘制图形的颜色总是替换当前颜色缓冲区中存在的颜色,这样后面的物体总是覆盖在原有的物体上。但是当想要绘制类似于玻璃、水等具有透明效果的物体时,这种方法显然满足不了要求。通过定义一个表示物体半透明度的alpha值和一个半透明计算公式,可以将要绘制的物体颜色与颜色缓冲区中存在的颜色相混合,从而绘制出具有半透明效果的物体。Direct3D计算alpha颜色混合的方法如下:
color = (RGBsrc * Ksrc) OP (RGBdst * Kdst)
其中color表示alpha混合后的颜色值,RGBsrc表示源颜色值,即将要绘制的图元的颜色值;Ksrc表示源混合系数,通常赋值为表示半透明程度的alpha值,也可以是属于枚举类型D3DBLEND的任意值,用来和RGBsrc相乘。RGBdst表示目标颜色值,即当前颜色缓冲区中的颜色值,Kdst表示目标混合系数,可以是属于枚举D3DBLEND的任意值,用来和RGBdst相乘。OP表示源计算结果与颜色缓冲区计算结果的混合方法,默认状态下OP为D3DBLEND_ADD,即源计算结果与颜色缓冲区计算结果相加。
图形显示中,对alpha混合最普遍的用法是:把Ksrc赋值为D3DBLEND_SRCALPHA,即当前绘制像素的alpha值;把Kdst赋值为D3DBLEND_INVSRCALPHA,即1减去当前绘制像素的alpha值;把OP赋值为D3DBLEND_ADD,使源计算结果和颜色缓冲区计算结果相加,这样一来,alpha混合颜色的公式变为:
color = (RGBsrc * Ksrc) + (RGBdst * Kdst)
上面的设置可以较好地模拟大多数半透明物体的效果。
启用alpha混合
想要绘制半透明物体,首先需要激活Direct3D的alpha混合运算,调用Direct3D渲染状态设置函数IDirect3DDevice9:::SetRenderState(),将第一个参数设置为D3DRS_ALPHABLENDENABLE,第二个参数设置为TRUE,可以激活alpha混合,代码如下:
g_device->SetRenderState(D3DRS_ALPHABLENDENABLE, TRUE);
设置alpha混合系数
在上面介绍的alpha混合原理中提到的源混合系数和目标混合系数,也是通过Direct3D渲染状态设置函数IDirect3DDevice9::SetRenderState()设置的。若将第一个参数设置为D3DRS_SRCBLEND,则用于设置源混合系数,若将第一个参数设置为D3DRS_DESTBLEND,则用于设置目标混合系数,第二个参数可以设置为D3DBLEND枚举常量,各具体枚举常量的含义如下:
Defines the supported blend mode.
typedef enum D3DBLEND
{
D3DBLEND_ZERO = 1,
D3DBLEND_ONE = 2,
D3DBLEND_SRCCOLOR = 3,
D3DBLEND_INVSRCCOLOR = 4,
D3DBLEND_SRCALPHA = 5,
D3DBLEND_INVSRCALPHA = 6,
D3DBLEND_DESTALPHA = 7,
D3DBLEND_INVDESTALPHA = 8,
D3DBLEND_DESTCOLOR = 9,
D3DBLEND_INVDESTCOLOR = 10,
D3DBLEND_SRCALPHASAT = 11,
D3DBLEND_BOTHSRCALPHA = 12,
D3DBLEND_BOTHINVSRCALPHA = 13,
D3DBLEND_BLENDFACTOR = 14,
D3DBLEND_INVBLENDFACTOR = 15,
D3DBLEND_SRCCOLOR2 = 16,
D3DBLEND_INVSRCCOLOR2 = 17,
D3DBLEND_FORCE_DWORD = 0x7fffffff,
} D3DBLEND, *LPD3DBLEND;
Constants
- D3DBLEND_ZERO
- Blend factor is (0, 0, 0, 0).
- D3DBLEND_ONE
- Blend factor is (1, 1, 1, 1).
- D3DBLEND_SRCCOLOR
- Blend factor is (Rs, Gs, Bs, As).
- D3DBLEND_INVSRCCOLOR
- Blend factor is (1 - Rs, 1 - Gs, 1 - Bs, 1 - As).
- D3DBLEND_SRCALPHA
- Blend factor is (As, As, As, As).
- D3DBLEND_INVSRCALPHA
- Blend factor is ( 1 - As, 1 - As, 1 - As, 1 - As).
- D3DBLEND_DESTALPHA
- Blend factor is (Ad Ad Ad Ad).
- D3DBLEND_INVDESTALPHA
- Blend factor is (1 - Ad 1 - Ad 1 - Ad 1 - Ad).
- D3DBLEND_DESTCOLOR
- Blend factor is (Rd, Gd, Bd, Ad).
- D3DBLEND_INVDESTCOLOR
- Blend factor is (1 - Rd, 1 - Gd, 1 - Bd, 1 - Ad).
- D3DBLEND_SRCALPHASAT
- Blend factor is (f, f, f, 1); where f = min(As, 1 - Ad).
- D3DBLEND_BOTHSRCALPHA
- Obsolete. Starting with DirectX 6, you can achieve the same effect by setting the source and destination blend factors to D3DBLEND_SRCALPHA and D3DBLEND_INVSRCALPHA in separate calls.
- D3DBLEND_BOTHINVSRCALPHA
- Source blend factor is (1 - As, 1 - As, 1 - As, 1 - As), and destination blend factor is (As, As, As, As); the destination blend selection is overridden. This blend mode is supported only for the D3DRS_SRCBLEND render state.
- D3DBLEND_BLENDFACTOR
- Constant color blending factor used by the frame-buffer blender. This blend mode is supported only if D3DPBLENDCAPS_BLENDFACTOR is set in the SrcBlendCaps or DestBlendCaps members of D3DCAPS9.
- D3DBLEND_INVBLENDFACTOR
- Inverted constant color-blending factor used by the frame-buffer blender. This blend mode is supported only if the D3DPBLENDCAPS_BLENDFACTOR bit is set in the SrcBlendCaps or DestBlendCapsmembers of D3DCAPS9.
- D3DBLEND_SRCCOLOR2
- Blend factor is (PSOutColor[1]r, PSOutColor[1]g, PSOutColor[1]b, not used). See Render Target Blending.
Differences between Direct3D 9 and Direct3D 9Ex: This flag is available in Direct3D 9Ex only.
- D3DBLEND_INVSRCCOLOR2
- Blend factor is (1 - PSOutColor[1]r, 1 - PSOutColor[1]g, 1 - PSOutColor[1]b, not used)). See Render Target Blending.
Differences between Direct3D 9 and Direct3D 9Ex: This flag is available in Direct3D 9Ex only.
- D3DBLEND_FORCE_DWORD
- Forces this enumeration to compile to 32 bits in size. Without this value, some compilers would allow this enumeration to compile to a size other than 32 bits. This value is not used.
Remarks
In the preceding member descriptions, the RGBA values of the source and destination are indicated by the s andd subscripts.
The values in this enumerated type are used by the following render states:
- D3DRS_DESTBLEND
- D3DRS_SRCBLEND
- D3DRS_DESTBLENDALPHA
- D3DRS_SRCBLENDALPHA
See D3DRENDERSTATETYPE
Render Target Blending
Direct3D 9Ex has improved text rendering capabilities. Rendering clear-type fonts would normally require two passes. To eliminate the second pass, a pixel shader can be used to output two colors, which we can call PSOutColor[0] and PSOutColor[1]. The first color would contain the standard 3 color components (RGB). The second color would contain 3 alpha components (one for each component of the first color).
These new blending modes are only used for text rendering on the first render target.
设置alpha混合系数的代码示例如下:
g_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_SRCALPHA);
g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVSRCALPHA);
设置alpha混合方法
alpha混合方法指定源颜色和目标颜色的混合方法,通过Direct3D渲染状态设置函数IDirect3DDevice9::SetRenderState()设置,其中第一个参数设置为 D3DRS_BLENDOP,第二个参数设置为D3DBLENDOP枚举常量,各常量的含义如下:
Defines the supported blend operations. See Remarks for definitions of terms.
typedef enum D3DBLENDOP
{
D3DBLENDOP_ADD = 1,
D3DBLENDOP_SUBTRACT = 2,
D3DBLENDOP_REVSUBTRACT = 3,
D3DBLENDOP_MIN = 4,
D3DBLENDOP_MAX = 5,
D3DBLENDOP_FORCE_DWORD = 0x7fffffff,
} D3DBLENDOP, *LPD3DBLENDOP;
Constants
- D3DBLENDOP_ADD
- The result is the destination added to the source. Result = Source + Destination
- D3DBLENDOP_SUBTRACT
- The result is the destination subtracted from to the source. Result = Source - Destination
- D3DBLENDOP_REVSUBTRACT
- The result is the source subtracted from the destination. Result = Destination - Source
- D3DBLENDOP_MIN
- The result is the minimum of the source and destination. Result = MIN(Source, Destination)
- D3DBLENDOP_MAX
- The result is the maximum of the source and destination. Result = MAX(Source, Destination)
- D3DBLENDOP_FORCE_DWORD
- Forces this enumeration to compile to 32 bits in size. Without this value, some compilers would allow this enumeration to compile to a size other than 32 bits. This value is not used.
Remarks
Source, Destination, and Result are defined as:
Term | Type | Description |
---|---|---|
Source | Input | Color of the source pixel before the operation. |
Destination | Input | Color of the pixel in the destination buffer before the operation. |
Result | Output | Returned value that is the blended color resulting from the operation. |
This enumerated type defines values used by the following render states:
- D3DRS_BLENDOP
- D3DRS_BLENDOPALPHA
示例程序:
该示例程序模拟了直升飞机螺旋桨的半透明效果。在程序的初始化阶段,载入Heli.x文件,它是一个包含直升飞机的三维模型文件,其中螺旋桨的材质漫反射属性为(R, G, B, A) = (0.183700; 0.183700; 0.183700; 0.500000; ),可以用文本方式打开Heli.x查看它的材质属性,Heli.x是一个文本格式的.x文件。
示例程序中没有设置alpha混合方法,所以应用程序将采用默认的alpha混合方法D3DBLEND_ADD,即将源计算结果与颜色缓冲区计算结果相加。由于直升机螺旋桨的材质的alpha值为0.5f,因此它的最终颜色就是50%的玻璃颜色加上50%的背景颜色。
按下数字键"1",激活alpha混合。
按下数字键"0",禁用alpha混合。
设置alpha混合方法为D3DBLENDOP_SUBTRACT的效果图,启用alpha混合时。
g_device->SetRenderState(D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT);
设置以下代码时的效果图,可以看到直升机变亮了,启用alpha混合:
g_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_DESTCOLOR);
设置以下代码时的效果图,可以看到直升机变暗了,启用alpha混合:
g_device->SetRenderState(D3DRS_SRCBLEND, D3DBLEND_ONE);
g_device->SetRenderState(D3DRS_DESTBLEND, D3DBLEND_INVDESTCOLOR);
可以根据需要自己修改设置,以实现不同的颜色混合效果。
由于alpha混合是当前绘制的像素颜色与颜色缓冲区中存在的颜色的混合运算,因此,在绘制半透明物体前,必须保证位于半透明物体后的物体先于半透明物体绘制,也就是说,先绘制不透明物体,再绘制半透明物体。
有些计算机硬件由于功能的限制,可能不支持某些混合方法,这时Direct3D会自动使用alpha混合方法D3DBLENDOP_ADD。