|
Base Type 2D vec 3D vec 4D vec Matrix TypesFloat vec2 vec3 vec4 Mat2 mat3 mat4 Mat2x2 mat2x3 mat2x4 Mat3x2 mat3x3 mat3x4 Mat4x2 mat4x3 mat4x4 Double dvec2 dvec3 dvec4 Dmat2 dmat3 dmat4 Dmat2x2 dmat2x3 dmat2x4 Dmat3x2 dmat3x3 dmat3x4 Dmat4x2 dmat4x3 dmat4x4 int ivec2 ivec3 ivec4 --- uint uvec2 uvec3 uvec4 --- bool bvec2 bvec3 bvec4 ---
Данные матричного типа с указанием обоих измерений, такие как mat4x3, первым числом содержать число столбцов, а вторым - рядов. Переменные, обозначенные таким типом данных, могут быть инициализированы таким же образом как и подобные им скаляры: vec3 velocity = vec3 (0.0, 2.0, 3.0); и конвертация между этими типами данных также возможна: ivec3 steps = ivec3 (velocity); Конструкторы векторов также могут быть использованы для усечения или облегчения вектора. Если в конструктор более короткого вектора попадает длинный вектор, конструктор усекает его до установленной длинны. vec4 color; vec3 RGB = vec3 (color); // now RGB only has three elements Схожим образом попав в конструктор векторы могут удлинняться. Скалярные данные могут трансформироваться в вектора, как например, vec3 white = vec3 (1.0); // white = (1.0, 1.0, 1.0) vec4 translucent = vec4 (white, 0.5); Матрицы строятся таким же образом и могут быть инициализированы в или диагональную матрицу, или полную. В случае с диагональными матрицами, в конструктор передается одно значение, и диагональ матрицы устанавливается на это значение, а все остальные числа равняются в ней нулю. m = mat3(4.0) = ⎛⎝ 4.0 0.0 0.0 0.0 4.0 0.0 0.0 0.0 4.0 ⎞⎠
Также возможно создание матрицы путём указания каждого её числового значения в конструкторе. Значения можно указать набором скаляров и векторов, главное, чтобы было указано достаточно значений и все они имели общий вид. Кроме того, матрицы определяются по приоритету столбца, то есть, значения указываются сначала по столбцам, а не по рядам, как в “С” при инициализации двухмерных массивов. Например, мы можем инициализировать матрицу три-на-три так: mat3 M = mat3 (1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0); или так: vec3 column1 = vec3 (1.0, 2.0, 3.0); vec3 column2 = vec3 (4.0, 5.0, 6.0); vec3 column3 = vec3 (7.0, 8.0, 9.0); mat3 M = mat3 (column1, column2, column3);
или даже так: vec2 column1 = vec2 (1.0, 2.0); vec2 column2 = vec2 (4.0, 5.0); vec2 column3 = vec2 (7.0, 8.0); mat3 M = mat3 (column1, 3.0, column2, 6.0, column3, 9.0);
или получить ту же матрицу: ⎛⎝ 1.0 4.0 7.0 2.0 5.0 8.0 3.0 6.0 9.0 ⎞⎠
Получение доступа к элементам матриц и векторов
Отдельные элементы векторов и матриц могут быть доступны и отмечены. Векторы поддерживают два типа элементов доступа: поименной и метод массивов. Матрицы используют двух-мерный и метод массивов.
Компоненты вектора, к которым получаем поименной доступ, например, 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
Таким методом можно создать массивы для практически любого типа данных и ресурса. Когда внутренняя (самая правая) часть измерений передаётся приложению, она изменяется быстрее всего из макета памяти.
Квалификаторы хранилищ
Типы тоже могут иметь модификаторы, которые влияют на их повеление. В GLSL заданы четыре квалификатора, как показано в Таблице 2.5, с указанием их поведения на глобальном уровне. Table 2.5 GLSL Type Modifiers
![]() ![]() ЧТО ПРОИСХОДИТ ВО ВЗРОСЛОЙ ЖИЗНИ? Если вы все еще «неправильно» связаны с матерью, вы избегаете отделения и независимого взрослого существования... ![]() Что вызывает тренды на фондовых и товарных рынках Объяснение теории грузового поезда Первые 17 лет моих рыночных исследований сводились к попыткам вычислить, когда этот... ![]() Что делать, если нет взаимности? А теперь спустимся с небес на землю. Приземлились? Продолжаем разговор... ![]() Система охраняемых территорий в США Изучение особо охраняемых природных территорий(ООПТ) США представляет особый интерес по многим причинам... Не нашли то, что искали? Воспользуйтесь поиском гугл на сайте:
|