Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
калачева перевод.docx
Скачиваний:
2
Добавлен:
01.07.2025
Размер:
237.97 Кб
Скачать

Получение доступа к элементам матриц и векторов

Отдельные элементы векторов и матриц могут быть доступны и отмечены. Векторы поддерживают два типа элементов доступа: поименной и метод массивов. Матрицы используют двух-мерный и метод массивов.

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

float red = color.r;

float v_y = velocity.y;

или использую нулевую индексированную схему. С помощью этого примера мы получим тот же результат, что и выше:

float red = color[0];

float v_y = velocity[1];

По сути, в Таблице 2.4 три типа наименований компонентов, которые на деле дают один результат. Разные настройки удобны для разъяснения, что вы делаете:

Таблица 2.4 Vector Component Accessors

Component Accessors Описание

(x, y, z, w) компоненты, связанные с положением

(r, g, b, a) компоненты, связанные в цветом

(s, t, p, q) компоненты текстурных координат

Обычно покомпонентный доступ используется в векторах для swizzling-компонентов, такими как, например, цвета, возможно для конверсии цвет-положение. К примеру, вы можете провести следующую операцию для назначения параметра “освещенности”, основанном на красном компоненте цвета ввода:

vec3 luminance = color.rrr;

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

color = color.abgr; // reverse the components of a color

Единственное ограничение заключается в том, что в одной строке кода можно изменять только один набор компонентов. То есть, нельзя сделать

vec4 color = otherColor.rgz; // Error: "z" is from a different group

Также ошибка компиляции может появиться из-за попытки доступа к элементам за пределами диапазона этого типа данных. Например,

vec2 pos;

float zPos = pos.z; // Error: no "z" component in 2D vectors

Матричные элементы доступны при использовании системы счисления массивов. Через матрицу можно получить доступ или к значению одного скаляра, или же к массиву элементов:

mat4 m = mat4(2.0);

vec4 zVec = m[2]; // get column 2 of the matrix

float yScale = m[1][1]; // or m[1].y works as well

Структуры

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

struct Particle {

float lifetime;

vec3 position;

vec3 velocity;

};

Particle p = Particle(10.0, pos, vel); // pos, vel are vec3s

Для обращения к элементам структуры используйте известную вам из “С” нотацию “dot”.

Массивы

GLSL также поддерживает массивы любых типов данных, в том числе, структуры. Также как с массивами данных в “С”, они обозначаются квадратными скобками [ ]. Диапазон элементов в массиве размера n=0 … n= -1. В отличие от “С”, ни положительные ни отрицательные индексы за пределами диапазона разрешимы. С варсии GLSL 4.3, массивы могут формироваться из массивов, предоставляя возможность работы многомерными данными. Однако версии до 4.3 (4.2 и ранние) на позволяют работать с массивами из массивов, то есть нельзя создать многомерный масив.

Массивы могут быть объявлены измеренными и неизмеренными. Вы можете задать неизмеренный массив заранее в виде массива переменных, а позднее задать им определенный размер. Заявка массива пользуется видо с квадратными скобками, как в

float coeff[3]; // an array of 3 floats

float[3] coeff; // same thing

int indices[]; // unsized. Redeclare later with a size

Массивы - тип данных первого класса GLSL, что означает, что они могут быть использованы и как параметры функции и как возвратные данные. Чтобы статично интернализовать массив значений, вы можете использовать конструктор

float coeff[3] = float[3](2.38, 3.14, 42.0);

Пространственное значение в конструкторе не обязательно.

Также как и в Java, массивы GLSL имеют неявный метод для объявления количества элементов, которые они содержат. Метод использования length(). Если вы хотите работать со всеми элементами в массиве, вот способ использования lenth():

for (int i = 0; i < coeff.length(); ++i) {

coeff[i] *= 2.0;

}

Метод length() также применим к векторам и матрицам. Длинна вектора - это количество составляющих его компонентов. А длинна матрицы - число столбцов в ней. Это именно то, что вам нужно при работе с синтаксисом массивов для индексации векторов и матриц (m[2] это третий столбец в матрице m).

mat3x4 m;

int c = m.length(); // number of columns in m: 3

int r = m[0].length(); // number of components in column vector 0: 4

Если длинна известна на момент компиляции, метод length() возвращает компиляционную постоянную, которую можно использовать там, где требуются компиляционные постоянные. Например,

mat4 m;

float diagonal[m.length()]; // array of size matching the matrix size

float x[gl_in.length()]; // array of size matching the number of

// geometry shader input vertices

Для всех векторов и матриц, и для большинства массивов, lenght() определяется на стадии компиляции. Хотя для некоторых массивов, lenght() не известна до момента привязки. Это происходит, когда массив зависит от привязки для вычисления размера нескольких шейдеров в одной стадии. Для шейдеров объектов буфера хранения (заявленных командой buffer), lenght() может оставаться неизвестной до момента визуализации. Если вы хотите получить компиляционную постоянную от lenght(), убедитесь, что задали размер массива в вашем шейдере перед использованием lenght()-метода.

Многомерный массивы на деле являются массивами из массивов и имеют схожий с “С” синтаксис:

float coeff[3][5]; // an array of size 3 of arrays of size 5

coeff[2][1] *= 2.0; // inner-dimension index is 1, outer is 2

coeff.length(); // this returns the constant 3

coeff[2]; // a one-dimensional array of size 5

coeff[2].length(); // this returns the constant 5

Таким методом можно создать массивы для практически любого типа данных и ресурса. Когда внутренняя (самая правая) часть измерений передаётся приложению, она изменяется быстрее всего из макета памяти.