Различия между AGSL и GLSL

AGSL и GLSL очень похожи по синтаксису, что позволяет перенести многие эффекты фрагментных шейдеров GLSL в Android с минимальными изменениями. AGSL исправляет набор функций GLSL на уровне GLSL ES 1.0 (язык шейдеров, используемый OpenGL ES 2.0), чтобы обеспечить максимальный охват устройств.

Фрагментный шейдер GLSL управляет всем поведением графического процессора между растеризатором и аппаратным обеспечением смешивания. Этот шейдер выполняет всю работу по вычислению цвета, и генерируемый им цвет — это именно то, что передается на этап смешивания конвейера. Когда вы пишете шейдер на AGSL, вы программируете этап графического конвейера Android. Многие языковые различия проистекают из этого.

Выполнение шейдера

Как и в шейдере GLSL, шейдер AGSL начинает выполнение в основной функции. В отличие от GLSL, функция принимает в качестве параметра положение шейдера в «локальных» координатах. Это похоже на gl_FragCoord , но вместо координат фреймбуфера эти координаты могли быть преобразованы до вызова вашего шейдера. Затем ваш шейдер возвращает цвет пикселя в виде vec4 со средней или высокой точностью (аналогично out vec4 color или gl_FragColor в GLSL).

mediump vec4 main(in vec2 fragCoord)

Координатное пространство

Координатные пространства GLSL и AGSL

Шейдер, нарисованный с использованием GLSL, и почти идентичный шейдер, нарисованный с использованием AGSL

AGSL и GLSL по умолчанию используют разные координатные пространства. В GLSL координата фрагмента (fragCoord) указывается относительно нижнего левого угла. AGSL соответствует системе координат экрана Canvas , что означает, что ось Y начинается с верхнего левого угла. При необходимости вы можете преобразовать между этими двумя пространствами, передав разрешение как единое целое и используя resolution.y - fragCoord.y для значения оси Y. Альтернативно вы можете применить к своему шейдеру локальную матрицу преобразования.

// AGSL to GLSL coordinate space transformation matrix
val localMatrix = Matrix()
localMatrix.postScale(1.0f, -1.0f)
localMatrix.postTranslate(0.0f, viewHeight)
gridShader.setLocalMatrix(localMatrix)

Точность и типы

Поддерживаются модификаторы точности, совместимые с GLSL, но AGSL представляет half и short типы, которые также представляют среднюю точность.

Векторные типы могут быть объявлены как названные <базовый тип><столбцы>. Вы можете использовать float2 вместо vec2 и bool4 вместо bvec4 . Типы матриц могут быть объявлены как <base type><columns>x<rows>, поэтому float3x3 вместо mat3 . AGSL также допускает объявления в стиле GLSL для mat и vec , и эти типы сопоставляются со своими эквивалентами с плавающей запятой.

Препроцессор

AGSL не поддерживает директивы препроцессора в стиле GLSL. Преобразуйте операторы #define в константные переменные. Компилятор AGSL поддерживает свертывание констант и исключение ветвей для константных переменных, поэтому они будут эффективны.

Цветовые пространства

Приложения Android управляются цветом. Цветовое пространство Canvas определяет рабочее цветовое пространство для рисования. Исходный контент (например, шейдеры, включая BitmapShader ) также имеет цветовые пространства.

Для некоторых эффектов, таких как физически точное освещение, математические расчеты следует выполнять в линейном цветовом пространстве. Чтобы помочь в этом, AGSL предоставляет следующие встроенные функции:

half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)

Они преобразуют цвета между рабочим цветовым пространством и цветовым пространством Android LINEAR_EXTENDED_SRGB . В этом пространстве используются основные цвета (гамма) sRGB и линейная передаточная функция. Он представляет значения за пределами гаммы sRGB, используя значения расширенного диапазона (ниже 0,0 и выше 1,0).

Униформа

Поскольку AGSL не знает, содержат ли униформы цвета, он не будет автоматически применять к ним преобразование цветов. Вы можете пометить half4 / float4 / vec4 с помощью layout(color) , что позволит Android узнать, что униформа будет использоваться в качестве цвета, что позволит Android преобразовать значение униформы в рабочее цветовое пространство.

В AGSL объявите униформу следующим образом:

layout(color) uniform half4 iColor;  // Input color
uniform float2 iResolution;          // Viewport resolution (pixels)

В коде Android вы можете установить униформу следующим образом:

shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())