标签:
所谓混合,目的就是解决一些需要叠加处理的材质问题,书中有个很好的例子:雾。
当然也有其它的用法,比如把2个不同材质叠加,产生各种神奇的效果(参见9.5.2节)。
混合的代码操作:
按照一贯的逻辑,我们在D3D里创建一个东西都是要填一大堆结构体,然后使用一个函数初始化,再在渲染步骤中进行进一步处理。这里一样。。。。
使用CreateBlendState初始化对混合的描述:
virtual HRESULT STDMETHODCALLTYPE CreateBlendState( /* [annotation] */ _In_ const D3D11_BLEND_DESC *pBlendStateDesc, /* [annotation] */ _Out_opt_ ID3D11BlendState **ppBlendState)
这个没什么好多说的,第一个参数是一个描述用的结构体,第二个参数用于返回。
主要是看第一个结构体:
typedef struct D3D11_BLEND_DESC { BOOL AlphaToCoverageEnable; BOOL IndependentBlendEnable; D3D11_RENDER_TARGET_BLEND_DESC RenderTarget[8]; } D3D11_BLEND_DESC;
书中有解释,第一个参数表示是否使用一个叫做alpha-to-coverage的多重采样技术,现在先不用设为false,第二个参数表示是否使用多目标同时渲染(这是啥。。。)这里设为false,那么只能使用RenderTarget[0] 进行渲染。
换句话说,前两个参数现在以我的技术来说,没啥软用。
第三个参数又是一个结构体:
typedef struct D3D11_RENDER_TARGET_BLEND_DESC { BOOL BlendEnable; D3D11_BLEND SrcBlend; D3D11_BLEND DestBlend; D3D11_BLEND_OP BlendOp; D3D11_BLEND SrcBlendAlpha; D3D11_BLEND DestBlendAlpha; D3D11_BLEND_OP BlendOpAlpha; UINT8 RenderTargetWriteMask; } D3D11_RENDER_TARGET_BLEND_DESC;
这是我们主要讨论的内容:
https://msdn.microsoft.com/en-us/library/windows/desktop/ff476200
可以看msdn的解释。
BlendEnable 默认false,设为true时表示使用混合
SrcBlend,DestBlend与SrcBlendAlpha,DestBlendAlpha都是枚举类型D3D11_BLEND的成员指定混合系数。
BlendOP与BlendOPAlpha是D3D11_BLEND的成员,指定了混合的操作符
先看混合的数学方程:
C = Csrc ⊗ Fsrc ? Cdst ⊗ Fdst
这里的Csrc指的是我们正在处理的那个像素的颜色,Cdes指的是已经处理好了,放在后台缓冲区的颜色(这里会有一个深度的问题,先不考虑)。在不开启混合的情况下,我们正在处理的颜色会覆盖掉后台的颜色。当使用混合时,后台的颜色与现在的颜色会通过上面的式子产生一个新的颜色
先看混合系数Fsrc与Fdst就是SrcBlend,DestBlend的枚举体定义:
typedef enum D3D11_BLEND { D3D11_BLEND_ZERO = 1, D3D11_BLEND_ONE = 2, D3D11_BLEND_SRC_COLOR = 3, D3D11_BLEND_INV_SRC_COLOR = 4, D3D11_BLEND_SRC_ALPHA = 5, D3D11_BLEND_INV_SRC_ALPHA = 6, D3D11_BLEND_DEST_ALPHA = 7, D3D11_BLEND_INV_DEST_ALPHA = 8, D3D11_BLEND_DEST_COLOR = 9, D3D11_BLEND_INV_DEST_COLOR = 10, D3D11_BLEND_SRC_ALPHA_SAT = 11, D3D11_BLEND_BLEND_FACTOR = 14, D3D11_BLEND_INV_BLEND_FACTOR = 15, D3D11_BLEND_SRC1_COLOR = 16, D3D11_BLEND_INV_SRC1_COLOR = 17, D3D11_BLEND_SRC1_ALPHA = 18, D3D11_BLEND_INV_SRC1_ALPHA = 19 } D3D11_BLEND;
这里我引用他人的翻译,地址:http://shiba.hpe.sh.cn/jiaoyanzu/WULI/Article1563
D3D11_BLEND_ZERO:F = (0, 0, 0)且F = 0 D3D11_BLEND_ONE:F = (1, 1, 1) 且F = 1 D3D11_BLEND_SRC_COLOR:F = (rs ,gs ,bs ) D3D11_BLEND_INV_SRC_COLOR:F = (1 - rs ,1 - gs ,1 - bs ) D3D11_BLEND_SRC_ALPHA:F = (as ,as ,as )且F = as D3D11_BLEND_INV_SRC_ALPHA:F = (1 − as,1 − as,1 − as)且F =1 − as D3D11_BLEND_DEST_ALPHA:F = (ad ,ad ,ad )且F = ad D3D11_BLEND_INV_DEST_ALPHA:F = (1 – ad,1 − ad,1 – ad)且F =1 – ad D3D11_BLEND_DEST_COLOR:F = (rd ,gd ,bd ) D3D11_BLEND_INV_DEST_COLOR:F = (1 – rd ,1 – gd ,1 – bd ) D3D11_BLEND_SRC_ALPHA_SAT:F = (as?, as?, as?)且F = as?,其中,as? = clamp(as , 0, 1) D3D11_BLEND_BLEND_FACTOR:F = (r,g,b)且F = a,其中,颜色(r,g,b,a)由ID3D11DeviceContext::OMSetBlendState方法的第2个参数指定(9.4节)。也就是说,我们可以将一个颜色指定为混合系数;在修改混合状态前,该颜色一直有效。 D3D11_BLEND_INV_BLEND_FACTOR:F = (1-r,1-g,1-b)且F = 1-a,其中,颜色(r,g,b,a)由ID3D11DeviceContext::OMSetBlendState方法的第2个参数指定(9.4节)。也就是说,我们可以将一个颜色指定为混合系数;在修改混合状态前,该颜色一直有效。
////
//
然后是操作符的定义了,操作符在数学式子中用?表示,结构中体就是BlendOP
typedef enum D3D11_BLEND_OP { D3D11_BLEND_OP_ADD = 1, //C = Csrc ⊗ Fsrc + Cdst ⊗ Fdst 加 D3D11_BLEND_OP_SUBTRACT = 2, //C = Cdst ⊗ Fdst - Csrc ⊗ Fsrc 减 D3D11_BLEND_OP_REV_SUBTRACT = 3, //C = Csrc ⊗ Fsrc - Cdst ⊗ Fdst 减法,反过来 D3D11_BLEND_OP_MIN = 4, //取小的 D3D11_BLEND_OP_MAX = 5 //取大的 } D3D11_BLEND_OP;
//////
最后还有一个元素:
RenderTargetWriteMask,这个参数对于写入的类型进行限制比如禁止RED颜色写入,可以是多个标志位的组合,如下:
typedef enum D3D11_COLOR_WRITE_ENABLE { D3D11_COLOR_WRITE_ENABLE_RED = 1, D3D11_COLOR_WRITE_ENABLE_GREEN = 2, D3D11_COLOR_WRITE_ENABLE_BLUE = 4, D3D11_COLOR_WRITE_ENABLE_ALPHA = 8, D3D11_COLOR_WRITE_ENABLE_ALL = (D3D11_COLOR_WRITE_ENABLE_RED|D3D11_COLOR_WRITE_ENABLE_GREEN| D3D11_COLOR_WRITE_ENABLE_BLUE | D3D11_COLOR_WRITE_ENABLE_ALPHA) } D3D11_COLOR_WRITE_ENABLE;
然后我的创建代码:
HRESULT DrawFunction::CreateBlending(void) { HRESULT hr = S_OK;//ret // 设置Blend描述 D3D11_BLEND_DESC blendDesc; ZeroMemory(&blendDesc, sizeof(blendDesc)); blendDesc.AlphaToCoverageEnable = FALSE; blendDesc.IndependentBlendEnable = FALSE; blendDesc.RenderTarget[0].BlendEnable = TRUE; blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_ONE; blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_ONE; blendDesc.RenderTarget[0].BlendOp = D3D11_BLEND_OP_SUBTRACT; blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_ONE; blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_ONE; blendDesc.RenderTarget[0].BlendOpAlpha = D3D11_BLEND_OP_SUBTRACT; blendDesc.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL; hr = dev->CreateBlendState(&blendDesc, &pBlendStateSub); blendDesc.RenderTarget[0].SrcBlend = D3D11_BLEND_SRC_ALPHA; blendDesc.RenderTarget[0].DestBlend = D3D11_BLEND_INV_SRC_ALPHA; blendDesc.RenderTarget[0].SrcBlendAlpha = D3D11_BLEND_SRC_ALPHA; blendDesc.RenderTarget[0].DestBlendAlpha = D3D11_BLEND_INV_SRC_ALPHA; hr = dev->CreateBlendState(&blendDesc, &pBlendStateAlpha); return hr; }
最后可以用OMSetBlendState设置,启用/关闭混合。
void OMSetBlendState( [in] ID3D10BlendState *pBlendState, [in] const FLOAT BlendFactor[4], [in] UINT SampleMask );
主要是第一个参数,设为NULL表示关闭混合(设为默认状态?)
其它的看一下我上传的简单的demon
标签:
原文地址:http://www.cnblogs.com/Windogs/p/5002688.html