Blending (Смешивание)
Blending - один из этапов графического конвейера, который работает после выполнения фрагментного (пиксельного) шейдера и post Depth/Stencil тестов.
Blending позволяет смешивать полученный в результате расчётов фрагментного шейдера цвет, и тот цвет, который находится в буфере кадра. Смешивание производится по формуле:
result = srcColor * srcBlend [blendOp] dstColor * dstBlend;
Где
srcColor - текущий цвет
dstColor - цвет из буфера кадра.
srcBlend и dstBlend - параметр, устанавливаемый программой, и может принимать следующие значения:
| Параметр | Название в Direct3D10 | Название в Direct3D9 | Название в OpenGL | Дополнение |
| (0, 0, 0, 0) | D3D10_BLEND_ZERO | D3DBLEND_ZERO | GL_ZERO | Все компоненты цвета умножаються на 0 |
| (1, 1, 1, 1) | D3D10_BLEND_ONE | D3DBLEND_ONE | GL_ONE | Все компоненты цвета умножаються на 1 |
| (Rs,Gs,Bs,As) | D3D10_BLEND_SRC_COLOR | D3DBLEND_SRCCOLOR | GL_SRC_COLOR | Покомпонентное умножение на source цвет |
| (1-Rs,1-Gs,1-Bs,1-As) | D3D10_BLEND_INV_SRC_COLOR | D3DBLEND_INVSRCCOLOR | GL_ONE_MINUS_SRC_COLOR | Цвет по-компонентно умножается на инвертированный source цвет |
| (As,As,As,As) | D3D10_BLEND_SRC_ALPHA | D3DBLEND_SRCALPHA | GL_SRC_ALPHA | Все компоненты цвета умножаются на source alpha |
| (1-As,1-As,1-As,1-As) | D3D10_BLEND_INV_SRC_ALPHA | D3DBLEND_INVSRCALPHA | GL_ONE_MINUS_SRC_ALPHA | Все компоненты цвета умножаются на инвертированную source alpha |
| (Ad,Ad,Ad,Ad) | D3D10_BLEND_DEST_ALPHA | D3DBLEND_DESTALPHA | GL_DST_ALPHA | Все компоненты цвета умножаются на destination alpha |
| (1-Ad,1-Ad,1-Ad,1-Ad) | D3D10_BLEND_INV_DEST_ALPHA | D3DBLEND_INVDESTALPHA | GL_ONE_MINUS_DST_ALPHA | Все компоненты цвета умножаются на инвертированную destination alpha |
| (Rd,Gd,Bd,Ad) | D3D10_BLEND_DEST_COLOR | D3DBLEND_DESTCOLOR | GL_DST_COLOR | Покомпонентное умножение на destination цвет |
| (1-Rd,1-Gd,1-Bd1-Ad) | D3D10_BLEND_INV_DEST_COLOR | D3DBLEND_INVDESTCOLOR | GL_ONE_MINUS_DST_COLOR | Цвет по-компонентно умножается на инвертированный destination цвет |
| (f,f,f,1) | - | D3DBLEND_SRCALPHASAT | GL_SRC_ALPHA_SATURATE | RGB умножается на f=min(As,1-Ad), A на единицу |
Надо отметить, что в OpenGL, версии 1.3 и ниже, установить параметр (Rs,Gs,Bs,As) для srcBlend или (Rd,Gd,Bd,Ad) для dstBlend можно только при наличии расширения GL_NV_blend_square, которое к счастью поддерживается видеокартами от GeForce256 и Radeon. Начиная с версии 1.4 данная возможность находиться в OpenGL ядре.
При наличии D3DPBLENDCAPS_BLENDFACTOR в DX или GL_EXT_blend_color в GL (в ядре с версии 1.2) с появляются дополнительные значения:
| Параметр | Название в Direct3D10 | Название в Direct3D9 | Название в OpenGL | Дополнение |
| (Rc,Gc,Bc,Ac) | D3D10_BLEND_BLEND_FACTOR | D3DBLEND_BLENDFACTOR | GL_CONSTANT_COLOR | Покомпонентное умножение на константный цвет |
| (1-Rc,1-Gc,1-Bc,1-Ac) | D3D10_BLEND_INV_BLEND_FACTOR | D3DBLEND_INVBLENDFACTOR | GL_ONE_MINUS_CONSTANT_COLOR | По-компонентное умножение на инв. константный цвет |
| (Ac,Ac,Ac,Ac) | D3D10_BLEND_BLEND_FACTOR | - | GL_CONSTANT_ALPHA | По-компонентное умножение на константную альфу |
| (1-Ac,1-Ac,1-Ac,1-Ac) | D3D10_BLEND_INV_BLEND_FACTOR | - | GL_ONE_MINUS_CONSTANT_ALPHA | Покомпонентное умножение на инв. константную альфу |
Индекс s - source, d - destination, c - constant.
По умолчанию srcBlend = (1, 1, 1, 1), а dstBlend = (0, 0, 0, 0)
Также при возможности видеокарты может быть установлена операция blendOp (Cs = srcColor * srcBlend, Cd = dstColor * dstBlend):
| Параметр | Название в Direct3D10 | Название в Direct3D9 | Название в OpenGL | Дополнение |
| Cs+ Cd | D3D10_BLEND_OP_ADD | D3DBLENDOP_ADD | GL_FUNC_ADD_EXT | Сложение (по умолчанию) |
| min(Cs, Cd) | D3D10_BLEND_OP_MIN | D3DBLENDOP_MIN | GL_MIN_EXT | Минимум (требует GL_EXT_blend_minmax\D3DPMISCCAPS_BLENDOP) |
| max(Cs, Cd) | D3D10_BLEND_OP_MAX | D3DBLENDOP_MAX | GL_MAX_EXT | Максимум (требует GL_EXT_blend_minmax\D3DPMISCCAPS_BLENDOP) |
| Cs - Cd | D3D10_BLEND_OP_SUBTRACT | D3DBLENDOP_SUBTRACT | GL_FUNC_SUBTRACT_EXT | Вычитание (требует GL_EXT_blend_subtract\D3DPMISCCAPS_BLENDOP) |
| Cd - Cs | D3D10_BLEND_OP_REV_SUBTRACT | D3DBLENDOP_REVSUBTRACT | GL_FUNC_REVERSE_SUBTRACT_EXT | Обратное вычитание (требует GL_EXT_blend_subtract\D3DPMISCCAPS_BLENDOP) |
(Поддержка начиная с Radeon8500 и GeForce2)
Существует также ГЛ расширение GL_EXT_blend_logic_op, позволяющее делать побитовые операции между Cs и Cd, но оно нам не интересно, так как поддерживается только картами ATI FireGL)
Для установки названных выше операций и параметров используются следующие функции:
Для включения блендинга
GL: glEnable(GL_BLEND); DX: SetRenderState( D3DRS_ALPHABLENDENABLE, true);
Для установки параметров srcBlend и dstBlend
GL: glBlendFunc(srcBlend, dstBlend); DX: SetRenderState( D3DRS_SRCBLEND, srcBlend); SetRenderState( D3DRS_DESTBLEND, dstBlend);
Для установки константного цвета
GL: glBlendColorEXT(r, g, b, a); DX: SetRenderState( D3DRS_BLENDFACTOR, D3DCOLOR( r, g, b, a));
Для установки blendOp
GL: glBlendEquationEXT(blendOp); DX: SetRenderState( D3DRS_BLENDOP, blendOp);
Но это ещё не все возможности стадии смешивания. Существуют дополнительные расширения, которые позволяют разделить операции, производимые над rgb цветом и альфой. Эта возможность называется separate alpha blend. При его включении блендинг производиться по формулам:
result.rgb = srcColor.rgb * srcBlend [blendOp] dstColor.rgb * dstBlend; result.a = srcColor.a * srcBlendAlpha [blendOp] dstColor.a * dstBlendAlpha;
Для параметров srcBlendAlpha и dstBlendAlpha используються типы, описанные в таблицах выше. Альфа умножается на четвёртую альфа-компоненту параметра.
В GL раздельный блендинг устанавливается командой
glBlendFuncSeparateEXT(srcBlend, dstBlend, srcBlendAlpha, dstBlendAlpha);
при поддержке расширения GL_EXT_blend_func_separate (Radeon8500+, GeForce5200+)
В DX используются функции
SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true); SetRenderState( D3DRS_SRCBLENDALPHA, srcBlendAlpha); SetRenderState( D3DRS_DESTBLENDALPHA, dstBlendAlpha);
при поддержке D3DPMISCCAPS_SEPARATEALPHABLEND
Но и это ещё не всё! Можно также установить отдельные blendOp's для rgb и альфы.
result.rgb = srcColor.rgb * srcBlend [blendOp] dstColor.rgb * dstBlend; result.a = srcColor.a * srcBlendAlpha [blendOpAlpha] dstColor.a * dstBlendAlpha;
В GL это производиться командой
glBlendEquationSeparateEXT(blendOp, blendOpAlpha);
при поддержке GL_EXT_blend_equation_separate (Radeon8500+ (только на Apple!), GeForce6100+)
В DX используется связка
SetRenderState(D3DRS_SEPARATEALPHABLENDENABLE, true); SetRenderState( D3DRS_BLENDOPALPHA, blendOpAlpha);
Что такое Blending (Смешивание)?
12 мая 2007 (Обновление: 18 апр 2013)
Комментарии [5]