D3D中的混合指的是目标像素(后台缓冲)源像素(光栅化像素)混合(blend)输出的过程。

一、影响最终的混合后输出结果的因素有个:混合因子,混合方法。

1)混合因子(D3D10_BLEND)。

混合因子共有19个。注意:有些混合因子以_COLOR结尾,有的以_ALPHA结尾。其中以_COLOR结尾的混合因子不能用于APPHA混合方程

混合因子分为源混合因子,目标混合因子。区别在于,前者指定的是源像素的比例,后者指定的是目标像素的比例。

2)混合方法(DD10_BLEND_OP)

混合方法有5中,一般常用的就是加、减、乘。

3)混合因子与混合方法的常用组合使用示例

1.屏蔽颜色写入,当我们希望屏蔽后台缓冲只向深度缓冲写入数据时。我们可以这样干,将源像素混合因子设为D3D10_BLEND_ZERO,目标像素混合因子设为D3D10_BLEND_ONE,混合方法设为D3D10_BLEND_OP_ADD

2.像素相加减 。源像素混合因子设为D3D10_BLEND_ONE,目标像素混合因子设为D3D10_BLEND_ONE,混合方法设为D3D10_BLEND_OP_ADD/SUBTRACT

3.像素相乘 。源像素混合因子设为D3D10_BLEND_ZERO,目标像素混合因子设为D3D10_BLEND_SRC_COLOR,混合方法设为D3D10_BLEND_OP_ADD

4.透明效果。 使用源像素的(光栅化像素)的ALPHA分量控制源像素的透明度。将源混合因子设为D3D10_BLEND_SRC_ALPHA,将目标混合因子设为D3D10_BLEND_INV_SRC_ALPHA,混合运算设为D3D10_BLEND_OP_ADD。

注意:当使用该种绘制效果时,要根据透明物体与摄像机之间的距离将物体的绘制顺序进行排序。按照从后向前的顺序进行绘制。(将透明物体后面所有物体先绘制出来,然后才能将透明的源像素和后台缓冲区的目标像素进行混合)

下面是示例:

二、使用混合的流程

定义混合状态(BLEND_STATE)——>启用混合状态——>绘制。

1)定义并创建、使用混合状态

混合状态是一个结构体。内容是:源混合因子,目标混合因子,混合方法,ALPHA源混合因子,ALPHA目标混合因子,ALPHA混合方法。渲染目标写入控制(是多个枚举变量的组合,用来控制何种颜色可以写图后台缓冲,当然也可以只写入ALPHA屏蔽RGB颜色)。

下面是创建并启用一个混合状态的例子(C++代码)

ID3D10BlendState* mTransparentBS;

D3D10_BLEND_DESC blendDesc = {0};
blendDesc.AlphaToCoverageEnable = false;//不启用AlphaToCoverage
blendDesc.BlendEnable[0] = true;//在索引为0的渲染目标中启用混合
blendDesc.SrcBlend       = D3D10_BLEND_SRC_ALPHA;
blendDesc.DestBlend      = D3D10_BLEND_INV_SRC_ALPHA;
blendDesc.BlendOp        = D3D10_BLEND_OP_ADD;    
blendDesc.SrcBlendAlpha  = D3D10_BLEND_ONE;
blendDesc.DestBlendAlpha = D3D10_BLEND_ZERO;
blendDesc.BlendOpAlpha   = D3D10_BLEND_OP_ADD;
blendDesc.RenderTargetWriteMask[0] = D3D10_COLOR_WRITE_ENABLE_ALL;//全部(RGB颜色和ALPHA都可以写入后台缓冲区)
float blendFactor[] = {0.0f, 0.0f, 0.0f, 0.0f};
//使用CreateBlendState函数创建blendstate
md3dDevice->CreateBlendState(&blendDesc, &mTransparentBS);
//使用OMSetBlendState函数,启用刚刚创建的blendstate
//第二个参数是用于描述RGB颜色向量的浮点数组,不过我不知道它具体是做什么的…悲伤
//第三个参数0xffffffff表示不屏蔽任何采样源
md3dDevice->OMSetBlendState(mTransparentBS, blendFactor, 0xffffffff);

注意:使用混合会在每个像素上进行工作,当我们不需要使用混合时应当马上将它关闭。以节省开销。关闭方法如下

//空值表示默认混合状态,也就是禁用混合
md3dDevice->OMSetBlendState(0);

最后的最后:像其他D3D接口一样,当我们要结束程序时,总要将它释放

mTransparentBS->release();
mTransparentBS = 0;

与渲染状态一样,混合状态也可以在效果文件中创建和设置。下面是HLSL代码

BlendState blend
{
  BlendEnable[0] = TRUE;
  SrcBlend  = SRC_COLOR;
  DestBlend = INV_SRC_ALPHA;
  BlendOp = ADD;
  SrcBlendAlpha = ZERO;
  DestBlendAlpha = ZERO;
  BlendOpAlpha = ADD;
  RenderTargetWiriteMask[0] = 0x0F;
};

technique Tech
{
   pass P0
   {
      ...
      SetBlendState(blend,float4(0.0f,0.0f,0.0f,0.0f),0xffffffff);
   }
}

 

posted on 2013-02-26 18:37  曾健  阅读(2104)  评论(2编辑  收藏  举报