Поделиться через


Настройка функциональных возможностей смешивания

Операции смешивания выполняются при каждом выходе шейдера пикселей (значение RGBA) перед записью выходного значения в целевой объект отрисовки. Если включен мультисэмплинг, смешивание выполняется для каждого мультисэмпла; в противном случае смешивание выполняется на каждом пикселе.

Создание состояния смешивания

Состояние смешивания — это коллекция состояний, используемых для управления смешиваниями. Эти состояния (определенные в D3D11_BLEND_DESC1) используются для создания объекта состояния смешения путем вызова ID3D11Device1::CreateBlendState1.

Например, вот очень простой пример создания состояния смешивания, которое отключает альфа-смешивание и не использует маскирование пикселей по компонентам.

ID3D11BlendState1* g_pBlendStateNoBlend = NULL;

D3D11_BLEND_DESC1 BlendState;
ZeroMemory(&BlendState, sizeof(D3D11_BLEND_DESC1));
BlendState.RenderTarget[0].BlendEnable = FALSE;
BlendState.RenderTarget[0].RenderTargetWriteMask = D3D11_COLOR_WRITE_ENABLE_ALL;
pd3dDevice->CreateBlendState1(&BlendState, &g_pBlendStateNoBlend);

Этот пример аналогичен примеру HLSLWithoutFX10.

Привязать состояние смешивания

После создания объекта blend-state привяжите объект состояния смешивания к стадии объединения выходных данных, вызвав метод ID3D11DeviceContext::OMSetBlendState.

float blendFactor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
UINT sampleMask   = 0xffffffff;

pd3dDevice->OMSetBlendState(g_pBlendStateNoBlend, blendFactor, sampleMask);

API принимает три параметра: объект состояния смешивания, четырехкомпонентный фактор смешивания и маску выборки. Можно передать NULL для объекта состояния смешивания, чтобы указать состояние смешивания по умолчанию, или передать объект состояния смешивания. Если вы создали объект состояния смешивания с D3D11_BLEND_BLEND_FACTOR или D3D11_BLEND_INV_BLEND_FACTOR, вы можете передать коэффициент смешивания для изменения значений шейдера пикселей, целевого объекта отрисовки или обоих объектов. Если объект blend-state не был создан с D3D11_BLEND_BLEND_FACTOR или D3D11_BLEND_INV_BLEND_FACTOR, вы по-прежнему можете передать ненулевой коэффициент смешивания, но этап смешивания не использует коэффициент смешивания; Среда выполнения сохраняет коэффициент смешивания, и вы можете позже вызвать ID3D11DeviceContext::OMGetBlendState для получения коэффициента смешивания. Если передать NULL, среда выполнения использует или сохраняет коэффициент смешивания, равный { 1, 1, 1, 1 }. Пример маски — это определяемая пользователем маска, которая определяет способ выборки существующего целевого объекта отрисовки перед обновлением. Маска выборки по умолчанию 0xffffffff, которая обозначает выборку точек.

В большинстве схем буферизации глубины именно пиксель, наиболее близкий к камере, отображается. При настройке состояния элементов глубиныD3D11_COMPARISON_FUNCDepthFuncD3D11_DEPTH_STENCIL_DESC может быть любым D3D11_COMPARISON_FUNC. Обычно вы бы хотели, чтобы DepthFunc было D3D11_COMPARISON_LESS, так, чтобы пиксели, ближайшие к камере, перезаписали пиксели за ними. Однако в зависимости от потребностей приложения можно использовать любые другие функции сравнения для тестирования глубины.

Продвинутые темы по смешиванию

Альфа-To-Coverage

Альфа-ковераж — это мультисэмплинговая техника, которая наиболее полезна для таких ситуаций, как плотная листва, где существует несколько перекрывающихся многоугольников, использующих альфа-прозрачность для определения краев на поверхности.

Вы можете использовать AlphaToCoverageEnable член D3D11_BLEND_DESC1 или D3D11_BLEND_DESC для переключения, определяет ли среда выполнения превращение .a компонента (альфа) выходного регистра SV_Target0 из пиксельного шейдера в n-ступенчатую маску покрытия (с учетом n-образца RenderTarget). Среда выполнения выполняет операцию И этой маски с типичным покрытием выборки для пикселя в примитиве (наряду с маской выборки), чтобы определить, какие сэмплы необходимо обновить во всех активных RenderTarget.

Если шейдер пикселей выводит SV_Coverage, среда выполнения отключает альфа-покрытие.

Заметка

В многосамплинге среда выполнения использует только одно покрытие для всех RenderTarget. Тот факт, что среда выполнения считывает и преобразует .a из выходных данных SV_Target0 в значение покрытия, когда AlphaToCoverageEnable установлено в TRUE, не изменяет значение .a, которое переходит к смешивателю на RenderTarget 0 (если RenderTarget установлен там). Как правило, если вы включите альфа-покрытие, вы не влияете на то, как все выходные данные цвета от шейдеров пикселей взаимодействуют с RenderTargetчерез этап слияния выходных данных за исключением того, что среда выполнения выполняет И операцию маски покрытия с маской покрытия альфа-в-покрытие. Альфа-покрытие работает независимо от того, может ли среда выполнения смешивать RenderTarget или вы осуществляете смешивание на RenderTarget.

 

Графическое оборудование точно не указывает, как оно преобразует шейдер пикселей SV_Target0.a (альфа) в маску покрытия, единственное указание заключается в том, что альфа, равная 0 (или меньше), должна сопоставляться с отсутствием покрытия, а альфа, равная 1 (или больше), должна сопоставляться с полным покрытием (прежде чем среда выполнения выполняет И операцию с фактическим примитивным покрытием). Как альфа идет от 0 до 1, результирующий охват должен обычно увеличиваться монотонно. Однако оборудование может выполнять дитеринг области, чтобы обеспечить более высокую квантизацию альфа-значений, что может привести к ухудшению пространственного разрешения и увеличению шума. Альфа-значение NaN (не число) приводит к созданию маски без покрытия (нуль).

Альфа-в-покрытие также традиционно используется для создания прозрачности с эффектом сетчатки экрана или для определения подробных силуэтов для непрозрачных спрайтов.

Смешивание выходных данных шейдера пикселей

Эта функция позволяет модулю слияния выходных данных использовать оба выходных сигнала пиксельного шейдера одновременно в качестве исходных данных для операции смешивания с единственной целью отрисовки в слоте 0.

Этот пример берет два результата и объединяет их в одном проходе: внедряя один с помощью умножения в место назначения, а другой — с помощью сложения.

SrcBlend = D3D11_BLEND_ONE;
DestBlend = D3D11_BLEND_SRC1_COLOR;

Этот пример настраивает первый вывод пиксельного шейдера как исходный цвет, а второй вывод как коэффициент перемешивания компонентов для каждого цвета.

SrcBlend = D3D11_BLEND_SRC1_COLOR;
DestBlend = D3D11_BLEND_INV_SRC1_COLOR;

В этом примере показано, как факторы смешивания должны соответствовать свизлам шейдера.

SrcFactor = D3D11_BLEND_SRC1_ALPHA;
DestFactor = D3D11_BLEND_SRC_COLOR;
OutputWriteMask[0] = .ra; // pseudocode for setting the mask at
                          // RenderTarget slot 0 to .ra

Вместе факторы смешивания и код шейдера подразумевают, что шейдер пикселей должен выводить по крайней мере o0.r и o1.a. Дополнительные выходные компоненты могут выводиться шейдером, но будут игнорироваться, а меньшее количество компонентов приведет к неопределенным результатам.

этап Output-Merger

этапы конвейера (Direct3D 10)