Операторы
HLSL поддерживает иного операторов, похожих на те, что есть в C++. За исключением нескольких особенностей, о которых мы поговорим ниже, эти операторы работают точно так же, как и их аналоги в C++. Ниже приведен список поддерживаемых в HLSL операторов:
[] . > < <= >= != == ! && || ?: + += – –= * *= / /= % %= ++ –– = () ,
Хотя поведение операторов очень похоже на С++, есть несколько отличий. Во-первых, операция деления по модулю работает как для целых чисел, так и для чисел с плавающей точкой. Кроме того, для операции деления по модулю необходимо, чтобы у обоих ее операндов был один и тот же знак (то есть, чтобы либо оба операнда были положительными, либо оба отрицательными).
Во-вторых, обратите внимание, что большинство операторов HLSL действуют покомпонентно. Это вызвано тем фактом, что векторы и матрицы встроены в язык, а эти типы состоят из отдельных компонентов. Благодаря наличию операторов, работающих на уровне компонентов, такие операции как сложение векторов/матриц, вычитание векторов/матриц и проверка равенства векторов/матриц выполняются с использованием тех же операторов, которые применяются для скалярных типов. Взгляните на следующие примеры:
ПРИМЕЧАНИЕ
vector u = {1.0f, 0.0f, -3.0f, 1.0f}; vector v = {-4.0f, 2.0f, 1.0f, 0.0f};
// Складываем соответствующие компоненты vector sum = u + v; // сумма = (-3.0f, 2.0f, -2.0f, 1.0f)
Инкремент вектора увеличивает каждую из его компонент:
// до инкремента: sum = (-3.0f, 2.0f, -2.0f, 1.0f)
sum++; // после инкремента: sum = (-2.0f, 3.0f, -1.0f, 2.0f)
Покомпонентное произведение векторов:
vector u = {1.0f, 0.0f, -3.0f, 1.0f}; vector v = {-4.0f, 2.0f, 1.0f, 0.0f};
// Умножаем соответствующие компоненты vector sum = u * v; // произведение = (-4.0f, 0.0f, -3.0f, 0.0f)
Операторы сравнения тоже работают покомпонентно и возвращают вектор или матрицу, каждый элемент которой является логическим значением. Полученный в результате «логический» вектор содержит результаты сравнения соответствующих компонент его операндов.
Например:
vector u = { 1.0f, 0.0f, -3.0f, 1.0f}; vector v = {-4.0f, 0.0f, 1.0f, 1.0f};
vector b = (u == v); // b = (false, true, false, true)
И, в заключение, мы рассмотрим повышение типа переменной при бинарных операциях:
Если в бинарной операции размер левого операнда отличается от размера правого операнда, то операнд меньшего размера повышается (приводится) до типа операнда большего размера. Например, если переменная x типа float, а переменная y типа float3, то в выражении (x + y) переменная x будет повышена до типа float3 и результатом всего выражения также будет значение типа float3. При повышении типа используются предопределенные правила приведения типов. В рассматриваемом случае мы преобразуем скаляр в вектор; следовательно, после повышения x до float3, x = (x, x, x), как указано в правилах приведения скалярных типов к векторным. Помните, что результат повышения не определен, если не определена соответствующая операция приведения. Например, мы не можем выполнить повышение float2 до float3 поскольку такая операция приведения типа не существует.
Если в бинарной операции диапазон значений левого операнда отличается от диапазона значений правого операнда, то операнд с меньшим диапазоном значений повышается (приводится) до типа операнда с большим диапазоном значений. Например, если переменная x типа int, а переменная y типа half, то в выражении (x + y) переменная x будет повышена до типа half и результатом всего выражения также будет значение типа half.