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


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

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

Создание состояния Blend

Состояние смешения — это коллекция состояний, используемых для управления смешения. Эти состояния (определенные в 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

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

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

Дополнительные темы по наложению

Альфа-охват

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

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

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

Примечание

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

 

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

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

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

Эта функция позволяет слиянию выходных данных одновременно использовать оба выходных данных шейдера пикселей в качестве источников входных данных для операции смешивания с одним целевым объектом отрисовки в слоте 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 требуется пиксельный шейдер. Дополнительные выходные компоненты могут выводиться шейдером, но будут игнорироваться, меньшее количество компонентов даст неопределенные результаты.

Стадия средства слияния вывода

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