Плоскости клипа пользователя на оборудовании уровня компонентов 9

Начиная с Windows 8, microsoft High Level Shader Language (HLSL) поддерживает синтаксис, который можно использовать с API Microsoft Direct3D 11 для указания плоскостей клипов пользователей на уровне компонентов 9_x и выше. Этот синтаксис клиповых плоскостей можно использовать для написания шейдера, а затем использовать этот объект шейдера с API Direct3D 11 для запуска на всех уровнях функций Direct3D.

История

Доступ к плоскостям клипов пользователей в API Microsoft Direct3D 9 можно получить с помощью методов IDirect3DDevice9::SetClipPlane и IDirect3DDevice9::GetClipPlane . В Microsoft Direct3D 10 и более поздних версий вы можете получить доступ к плоскостям клипов пользователей через SV_ClipDistance семантику. Но до Windows 8 SV_ClipDistance не были доступны для оборудования уровня функций 9_x в API Direct3D 10 или Direct3D 11. Таким образом, до Windows 8 единственным способом получить доступ к плоскостям клипов пользователей с помощью 9_x оборудования на уровне функций был API Direct3D 9. Приложения Direct3D из Магазина Windows не могут использовать API Direct3D 9. Здесь описывается синтаксис, который можно использовать для доступа к плоскостям клипов пользователей через API Direct3D 11 на уровне компонентов 9_x и выше.

Приложения используют клиповые плоскости для определения набора невидимых плоскостей в трехмерном мире, которые обрезают (выбрасывают) все нарисованные примитивы. Windows не будет рисовать пиксель, который находится на отрицательной стороне каких-либо плоскостей клипа. Затем приложения могут использовать плоскости клипа для отрисовки планарных отражений.

Синтаксис

Используйте этот синтаксис для объявления плоскостей клипа в качестве атрибутов функции в объявлении функции. Например, здесь используется синтаксис фрагмента вершинного шейдера:

cbuffer ClipPlaneConstantBuffer 
{
       float4 clipPlane1;
       float4 clipPlane2;
};

[clipplanes(clipPlane1,clipPlane2)]
VertexShaderOutput main(VertexShaderInput input)
{
       // the rest of the vertex shader doesn't refer to the clip plane
 
       …
 
       return output;
}

В этом примере для фрагмента вершинного шейдера обозначается две плоскости клипа. Он показывает, что необходимо поместить новый атрибут clipplanes в квадратные скобки непосредственно перед возвращаемым значением вершинного шейдера. В скобках после атрибута clipplanes предоставляется список до 6 констант float4 , определяющих коэффициенты плоскости для каждого активного плоскости клипа. В примере также показано, что необходимо сделать так, чтобы коэффициенты каждой плоскости находились в буфере констант.

Примечание

Для динамического отключения плоскости клипов нет синтаксиса. Необходимо либо перекомпилировать идентичный шейдер без атрибута clipplanes , либо приложение может установить коэффициенты в буфере констант равным нулю, чтобы плоскость больше не влияла на геометрию.

 

Этот синтаксис доступен для любого целевого шейдера вершин 4.0 или более поздней версии, который включает vs_4_0_level_9_1 и vs_4_0_level_9_3.

Создание плоскостей клипа в пространстве клипа на уровне компонентов 9 и выше

Здесь мы покажем, как создавать плоскости клипа в пространстве клипов на уровне функций 9_x и выше.

Фоновое чтение

В книге "Введение в программирование трехмерных игр с помощью DirectX 10" Фрэнка Д. Луны объясняется, что необходимо для математики графики (главы 1, 2 и 3), а также различные пробелы и преобразования пространства, происходящие в вершинном шейдере (разделы 5.6 и 5.8).

Уровни функций 10Level9

В Direct3D 10 и более поздних версий можно обрезать в любом пространстве, которое имеет смысл, часто в мировом пространстве или пространстве просмотра. Но Direct3D 9 использует пространство клипа, которое является пространством проекции перед перспективой деления. Векторы находятся в пространстве клипа, когда вершинный шейдер передает их на этапы, следующие в графическом конвейере.

При написании приложения Магазина Windows необходимо использовать уровни компонентов 10Level9 (9_x уровня компонентов ), чтобы приложение можно было запускать на уровне компонентов 9_x и более поздних версий оборудования. Так как приложение поддерживает 9_x и выше, необходимо также использовать общую возможность применения плоскостей клипа в пространстве клипа.

При компиляции вершинного шейдера с vs_4_0_level_9_1 или более поздней версии этот вершинный шейдер может использовать атрибут clipplanes . Объект Direct3D 10 или более поздней версии имеет точечное произведение выдаваемой вершины, содержащее каждую из глобальных констант float4 , указанных в атрибуте . Объект Direct3D 9 имеет достаточно метаданных, чтобы среда выполнения 10Level9 вызывала соответствующие вызовы IDirect3Device9::SetClipPlane.

Математика плоскости клипа

Плоскость клипа определяется вектором с 4 компонентами. Первые три компонента определяют вектор x, y, z, который исходит от источника в пространстве, которое требуется обрезать. Этот вектор подразумевает плоскость, перпендикулярную вектору и пробежающую через источник. Windows сохраняет все пиксели на стороне вектора плоскости и обрезает все пиксели за плоскостью. Четвертый компонент w отодвигает плоскость назад и приводит к уменьшению обрезки Windows (отрицательный w вызывает больше обрезки Windows) вдоль линии вектора. Если компоненты x, y, z составляют единицу (нормализованный) вектор, w отталкивает плоскость w единиц назад.

Математические вычисления, которые выполняет графический процессор (GPU) для определения обрезки, представляет собой простое точечный продукт между вектором вершин (x, y, z, 1) и вектором плоскости обрезки. Эта математическая операция создает длину проекции в векторе плоскости клипа. Отрицательное точечное произведение показывает, что вершина находится на обрезанной стороне плоскости.

Обрезка в пространстве представлений

Вот наша вершина в пространстве представлений:

вершина в пространстве представлений

Вот наш плоскость клипов в пространстве представлений:

плоскость клипа в пространстве представлений

Вот точечное произведение вершины и плоскости клипа в пространстве представлений:

ClipDistance = v · C = vCₓ +vyCy + vzCzC z + C w

Эта математическая операция работает для объекта Direct3D 10 или более поздней версии, но не работает для объекта Direct3D 9. Для Direct3D 9 необходимо сначала выполнить преобразование проекции в пространство клипа.

Матрица проекции

Матрица проекции преобразует вершину из пространства просмотра (где источником является глаз зрителя, +x — справа, +y — вверх, а +z — прямо) в пространство клипа. Матрица проекции считывает вершину для аппаратной отсечки и этапа растеризации. Ниже приведена стандартная матрица перспективы (для других проекций требуется другая математика):

*r* соотношение ширины и высоты окна *α* угол обзора *f* расстояние от зрителя до дальней плоскости *n* расстояние от зрителя до ближней плоскости
! [матрица проекции] (images/projection-matrix.png)

Следующая матрица представляет собой упрощенную версию предыдущей матрицы. Мы упростим матрицу, чтобы мы могли использовать ее позже в операции умножения матрицы.

упрощенная матрица проекции

Теперь мы преобразуем вершину пространства представления в пространство клипа с помощью матричного умножения:

матрица умножения

В нашей операции умножения матрицы компоненты x и y немного скорректированы, но компоненты z и w довольно искажены. Наш клип плоскость больше не даст нам то, что мы хотим.

Плоскость клипа клипа

Здесь мы хотим создать плоскость клипа, точка которого с вершиной пространства клипа дает нам то же значение, что и v · C в разделе Обрезка пространства представления .

Плоскость клипа

v · C = V P · CP

vCₓ +vyCy + vzCz + Cw = vPCPₓ +vyPyCPy + CvzAyCPz + BCPp v + zCPw

Теперь мы можем разбить предыдущую математическую операцию по компоненту вершины на четыре отдельных уравнения:

Компонент вершины x продукта плоскости клипа

Компонент вершины y продукта плоскости клипа

Компонент вершины в продукте плоскости клипа

Компонент вершины z продукта плоскости клипа

Наша плоскость клипов представления и матрица проекции получают и дают нам наш плоскость клипа.

плоскость клипа клипа

Руководство по программированию для HLSL

Синтаксис объявления функций