Краткий справочник по AGSL

AGSL в основном совместим с GLSL ES 1.0. Дополнительную информацию можно найти в документации по языку шейдеров OpenGL ES. В этой документации мы постарались указать различия между AGSL и GLSL.

Типы

AGSL поддерживает типы GLSL ES 1.0, а также дополнительный способ представления типов векторов и матриц. AGSL поддерживает дополнительные типы short и half для представления средней точности.

Основные типы

Тип Описание
void Функция не возвращает значение или список параметров пуст. В отличие от GLSL, функции без типа возвращаемого значения void должны возвращать значение.
bool, bvec2, bvec3, bvec4
(bool2, bool3, bool4).
Логический скаляр/вектор
int, ivec2, ivec3, ivec4
(int2, int3, int4)
highp, целое число со знаком/вектор
float, vec2, vec3, vec4
(float2, float3, float4)
highp (одинарная точность) с плавающей запятой, скаляр/вектор
short, short2, short3, short4 эквивалентно mediump int знаковому целому числу/вектору
half, half2, half3, half4 эквивалентно скаляру/вектору mediump float
mat2, mat3, mat4
(float2x2, float3x3, float4x4)
Матрица float 2 x 2, 3 x 3, 4 x 4
half2x2, half3x3, half4x4 Эквивалент типов матриц mediump float

Минимальные значения точности и диапазона

Ниже приведены минимальные гарантированные точность и диапазон, связанные с каждым модификатором, на основе спецификации OpenGL ES 2.0. Поскольку большинство устройств поддерживает ES 3.0, они будут иметь более гарантированную точность/диапазон highp и диапазон int mediump. Модификаторы точности можно применять к скалярным, векторным и матричным переменным и параметрам. Гарантируются только минимальные значения, указанные ниже. lowp не обязательно имеет меньшую точность, чем mediump, а mediump – меньшую точность, чем highp. В настоящее время AGSL преобразует lowp в mediump в конечном результате.

Модификатор Диапазон float Диапазон значений float Точность float Диапазон int
highp \(\left\{-2^{62},2^{62}\right\}\) \(\left\{2^{-62},2^{62}\right\}\) Относительный: \(2^{-16}\) \(\left\{-2^{16},2^{16}\right\}\)
mediump \(\left\{-2^{14},2^{14}\right\}\) \(\left\{2^{-14},2^{14}\right\}\) Относительный: \(2^{-10}\) \(\left\{-2^{10},2^{10}\right\}\)
lowp \(\left\{-2,2\right\}\) \(\left\{2^{-8},2\right\}\) Абсолютное: \(2^{-8}\) \(\left\{-2^{8},2^{8}\right\}\)

Помимо синтаксиса числовых индексов массивов (например, var[num]), названия компонентов векторов длиной 2–4 обозначаются одной буквой. Компоненты можно менять местами и дублировать, например vect.yx, vect.yy.

vect.xyzw – используйте при доступе к векторам, представляющим точки/нормали.

vect.rgba – используется при доступе к векторам, представляющим цвета.

vect.LTRB – используется, когда вектор представляет прямоугольник (не в GLSL).

В AGSL 0 и 1 можно использовать для создания константы 0 или 1 в этом канале. Пример: vect.rgb1 == vec4(vect.rgb,1)

Структуры и массивы

Структуры объявляются с тем же синтаксисом, что и GLSL, но AGSL поддерживает структуры только в глобальной области видимости.

struct type-name {
 members
} struct-name; // optional variable declaration.

Поддерживаются только одномерные массивы с явным указанием размера. Синтаксис может быть в стиле C или GLSL:

<базовый тип>[<размер массива>] имя переменной, например half[10] x;

<base type> variable name[<array size>] – пример: half x[10];

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

Отборочный этап

Тип Описание
const Константа времени компиляции или параметр функции, доступный только для чтения.
uniform Значение не меняется в пределах обрабатываемого примитива. Униформы передаются из Android с помощью методов RuntimeShader для setColorUniform, setFloatUniform, setIntUniform, setInputBuffer и setInputShader.
in Для параметров переданной функции. Это значение используется по умолчанию.
out Для параметров функции, которые передаются в ответ. Должна использоваться та же точность, что и в определении функции.
inout Для параметров, которые передаются в функцию и из нее. Должна использоваться та же точность, что и в определении функции.

Объявление переменной

Объявления должны находиться в явной области видимости, ограниченной фигурными скобками. В примере ниже объявление y недопустимо:

if (condition)
    int y = 0;

Основы матриц, структур и массивов

Примеры конструктора матриц

Если матрица создается с одним значением, все значения по диагонали получают это значение, а остальные – нули. float2x2(1.0) создаст единичную матрицу 2 x 2.

Если матрица состоит из нескольких значений, сначала заполняются столбцы (порядок по столбцам).

Обратите внимание, что в отличие от GLSL, конструкторы, которые уменьшают количество компонентов переданного вектора, не поддерживаются, но вы можете использовать свиззлинг, чтобы получить тот же эффект. Чтобы создать vec3 из vec4 в AGSL с тем же поведением, что и в GLSL, укажите vec3 nv = quadVec.xyz.

Пример конструктора структуры

struct light { float intensity; float3 pos; };
// literal integer constants auto-converted to floating point
light lightVar = light(3, float3(1, 2, 3.0));

Компоненты матрицы

Доступ к компонентам матрицы с помощью синтаксиса индексации массива.

float4x4 m; // represents a matrix
m[1] = float4(2.0); // sets second column to all 2.0
m[0][0] = 1.0; // sets upper left element to 1.0
m[2][3] = 2.0; // sets 4th element of 3rd column to 2.0

Поля структуры

Выберите поля структуры с помощью оператора точки .. Операторы:

Оператор Описание
. селектор полей
==, != равенство
= назначение

Элементы массива

Доступ к элементам массива осуществляется с помощью оператора индекса массива [ ]. Пример:

diffuseColor += lightIntensity[3] * NdotL;

Операторы

Пронумерованы в порядке приоритета. Операторы отношения и равенства > < <= >= == != возвращают логическое значение. Для покомпонентного сравнения векторов используйте функции lessThan(), equal() и т. д.

Оператор Описание Ассоциативность
1 () группировка в скобках Н/Д
2 [] () . ++ -- индекс массива вызов функции и конструктор поле или метод селектор, swizzle постфиксный инкремент и декремент Слева направо
3 ++ -- + - ! префиксный инкремент и декремент унарный Справа налево
4 * / умножать и делить Слева направо
5 + - сложение и вычитание Слева направо
7 < > <= >= реляционный Слева направо
8 == != равенство/неравенство; Слева направо
12 && логическое И Слева направо
13 ^^ логическое исключающее ИЛИ Слева направо
14 || логическое ИЛИ Слева направо
15 ?\: выделение (один полный операнд) Слева направо
16 = += -= *= /= assignment arithmetic assignment arithmetic assignment Слева направо
17 , sequence Слева направо

Операции с матрицами и векторами

При применении к скалярным значениям арифметические операторы возвращают скаляр. Для операторов, отличных от деления по модулю, если один операнд является скаляром, а другой – вектором или матрицей, операция выполняется покомпонентно и приводит к тому же типу вектора или матрицы. Если оба операнда являются векторами одного размера, операция выполняется покомпонентно (и возвращает вектор того же типа).

Операция Описание
m = f * m Покомпонентное умножение матрицы на скалярное значение
v = f * v Покомпонентное умножение вектора на скалярное значение
v = v * v Покомпонентное умножение вектора на векторное значение
m = m + m Покомпонентное сложение матриц
m = m - m Покомпонентное вычитание матриц
m = m * m Линейное алгебраическое умножение

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

Операция Описание
m = v * m Линейное алгебраическое умножение вектора-строки на матрицу
m = m * v Линейное алгебраическое умножение матрицы на вектор-столбец

Используйте встроенные функции для скалярного, векторного и покомпонентного умножения:

Функция Описание
f = dot(v, v) Скалярное произведение векторов
v = cross(v, v) Векторное произведение
m = matrixCompMult(m, m) Покомпонентное умножение

Управление программой

Вызов функции Вызов по значению-результату
Цикл for (<init>;<test>;<next>)
{ break, continue }
Выбор if ( ) { }
if ( ) { } else { }
switch () { break, case } - default case last
Прыжок break, continue, return
(отмена не разрешена)
Запись half4 main(float2 fragCoord)

Ограничения цикла for

Как и в GLSL ES 1.0, циклы for имеют ограничения. Компилятор должен иметь возможность развернуть цикл. Это означает, что инициализатор, условие теста и оператор next должны использовать константы, чтобы все можно было вычислить во время компиляции. Оператор next также ограничен использованием ++, --, +=, or -=.

Встроенные функции

GT (общий тип) – float, float2, float3, float4, half, half2, half3 или half4.

Большинство этих функций работают покомпонентно (функция применяется к каждому компоненту). Если это не так, мы указываем это отдельно.

Угловые и тригонометрические функции

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

Функция Описание
GT radians(GT degrees) Преобразует градусы в радианы.
GT degrees(GT radians) Преобразует радианы в градусы
GT sin(GT angle) Стандартный синус
GT cos(GT angle) Стандартная косинусная
GT tan(GT angle) Стандартная касательная
GT asin(GT x) Возвращает угол, синус которого равен x в диапазоне $ \left[-{\pi\over 2},{\pi\over 2}\right] $.
GT acos(GT x) Возвращает угол, косинус которого равен x, в диапазоне $ \left[0,\pi\right] $.
GT atan(GT y, GT x) Возвращает угол, тригонометрический арктангенс которого равен $ \left[{y\over x}\right] $ в диапазоне $ \left[-\pi,\pi\right] $.
GT atan(GT y_over_x) Возвращает угол, тригонометрический арктангенс которого равен y_over_x в диапазоне $ \left[-{\pi\over 2},{\pi\over 2}\right] $.

Показательные функции

Функция Описание
GT pow(GT x, GT y) Возвращает $ x^y $
GT exp(GT x) Возвращает $ e^x $
GT log(GT x) Возвращает $ ln(x) $
GT exp2(GT x) Возвращает $ 2^x $
GT log2(GT x) Возвращает $ log_2(x) $
GT sqrt(GT x) Возвращает $ \sqrt{x} $
GT inversesqrt(GT x) Возвращает $ 1\over{\sqrt{x}} $

Основные функции

Функция Описание
GT abs(GT x) Абсолютное значение
GT sign(GT x) Возвращает -1.0, 0.0 или 1.0 в зависимости от знака x.
GT floor(GT x) Ближайшее целое число <= x
GT ceil(GT x) Ближайшее целое число >= x
GT fract(GT x) Возвращает дробную часть x.
GT mod(GT x, GT y) Возвращает значение x по модулю y.
GT mod(GT x, float y) Возвращает остаток от деления x на y.
GT min(GT x, GT y) Возвращает минимальное значение x или y.
GT min(GT x, float y) Возвращает минимальное значение x или y.
GT max(GT x, GT y) Возвращает максимальное значение x или y.
GT max(GT x, float y) Возвращает максимальное значение x или y.
GT clamp(GT x, GT minVal, GT maxVal) Возвращает x, ограниченный между minVal и maxVal.
GT clamp(GT x, float minVal, float maxVal) Возвращает x, ограниченный между minVal и maxVal.
GT saturate(GT x) Возвращает x, ограниченный между 0,0 и 1,0.
GT mix(GT x, GT y, GT a) Возвращает линейное смешение x и y.
GT mix(GT x, GT y, float a) Возвращает линейное смешение x и y.
GT step(GT edge, GT x) Возвращает 0,0, если x < edge, в противном случае – 1,0.
GT step(float edge, GT x) Возвращает 0,0, если x < edge, в противном случае – 1,0.
GT smoothstep(GT edge0, GT edge1, GT x) Выполняет эрмитову интерполяцию между 0 и 1, если edge0 < x < edge1.
GT smoothstep(float edge0, float edge1, GT x) Выполняет эрмитову интерполяцию между 0 и 1, если edge0 < x < edge1.

Геометрические функции

Эти функции работают с векторами как с векторами, а не покомпонентно. GT – это векторы float/half размером 2–4.

Функция Описание
float/half length (GT x) Возвращает длину вектора.
float/half distance(GT p0, GT p1) Возвращает расстояние между точками
float/half dot(GT x, GT y) Возвращает скалярное произведение
float3/half3 cross(float3/half3 x, float3/half3 y) Возвращает декартово произведение
GT normalize(GT x) Нормализовать вектор до длины 1
GT faceforward(GT N, GT I, GT Nref) Возвращает N, если dot(Nref, I) < 0, иначе – -N.
GT reflect(GT I, GT N) Направление отражения I - 2 * dot(N,I) * N.
GT refract(GT I, GT N, float/half eta) Возвращает вектор преломления.

Матричные функции

Тип mat – это любой тип квадратной матрицы.

Функция Описание
mat matrixCompMult(mat x, mat y) Покомпонентно умножает x на y.
mat inverse(mat m) Возвращает обратную матрицу m.

Функции отношений векторов

Сравните x и y покомпонентно. Размеры входных и возвращаемых векторов для конкретного вызова должны совпадать. T – это объединение целочисленных типов и типов векторов с плавающей запятой. BV – логический вектор, соответствующий размеру входных векторов.

Функция Описание
BV lessThan(T x, T y) x < y
BV lessThanEqual(T x, T y) x <= y
BV greaterThan(T x, T y) x > y
BV greaterThanEqual(T x, T y) x >= y
BV equal(T x, T y) x == y
BV equal(BV x, BV y) x == y
BV notEqual(T x, T y) x != y
BV notEqual(BV x, BV y) x != y
bool any(BV x) true, если любой компонент x равен true.
bool all(BV x) true, если все компоненты x равны true.
BV not(BV x) Логическое дополнение x

Функции цвета

Функция Описание
vec4 unpremul(vec4 color) Преобразует значение цвета в непредумноженное значение альфа-канала.
half3 toLinearSrgb(half3 color) Преобразование цветового пространства в линейное sRGB
half3 fromLinearSrgb(half3 color) Преобразование цветового пространства

Выборка шейдеров (оценка)

Типы Sampler не поддерживаются, но вы можете оценивать другие шейдеры. Если вам нужно выполнить выборку текстуры, вы можете создать объект BitmapShader и добавить его как униформу. Это можно сделать для любого шейдера, то есть вы можете напрямую оценить любой шейдер Android, не преобразуя его сначала в Bitmap, включая другие объекты RuntimeShader. Это обеспечивает большую гибкость, но сложные шейдеры могут быть дорогими в вычислении, особенно в цикле.

uniform shader image;

image.eval(coord).a   // The alpha channel from the evaluated image shader

Выборка необработанного буфера

Хотя большинство изображений содержат цвета, которыми следует управлять, некоторые изображения содержат данные, которые на самом деле не являются цветами, включая изображения, хранящие нормали, свойства материала (например, шероховатость), карты высот или любые другие чисто математические данные, которые хранятся в изображении. При использовании таких изображений в AGSL вы можете использовать BitmapShader в качестве общего необработанного буфера с помощью RuntimeShader#setInputBuffer. Это позволит избежать преобразования цветового пространства и фильтрации.