AGSL 快速参考

AGSL 的设计在很大程度上与 GLSL ES 1.0 兼容。有关更多信息,请参阅OpenGL ES 着色语言文档中的等效函数。在可能的情况下,本文档会尝试指出 AGSL 和 GLSL 之间的差异。

类型

AGSL 支持 GLSL ES 1.0 类型以及表示向量和矩阵类型的另一种方法。AGSL 支持额外的shorthalf 类型来表示中等精度。

基本类型

类型 描述
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)
2x2、3x3、4x4 float 矩阵
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\}\)

除了数组数字下标语法 ex: var[num],长度为 2-4 的向量的向量组件名称由单个字母表示。组件可以交换和复制。ex:vect.yxvect.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;

<基本类型> 变量名[<数组大小>] - 例如:half x[10];

数组不能从函数返回、复制、赋值或比较。数组限制会传播到包含数组的结构体。数组只能使用常量或循环变量进行索引。

限定符

类型 描述
const 编译时常量或只读函数参数。
uniform 值在正在处理的图元中不会发生变化。使用 RuntimeShader 方法(setColorUniformsetFloatUniformsetIntUniformsetInputBuffersetInputShader)从 Android 传递制服。
in 用于传入函数参数。这是默认值。
out 用于传出函数参数。必须使用与函数定义相同的精度。
inout 用于既传入又传出函数的参数。必须使用与函数定义相同的精度。

变量声明

声明必须在显式的大括号范围内。以下示例中y 的声明是不允许的

if (condition)
    int y = 0;

矩阵/结构体/数组基础知识

矩阵构造函数示例

当使用单个值构造矩阵时,对角线上的所有值都将赋予该值,而其余值则赋予零。float2x2(1.0) 因此将创建一个 2x2 单位矩阵。

当使用多个值构造矩阵时,首先填充列(列主序)。

请注意,与 GLSL 不同,减少传入向量组件数量的构造函数不受支持,但您可以使用交换来获得相同的效果。要在 AGSL 中使用与 GLSL 相同的行为从 vec4 构造 vec3,请指定 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 () 括号分组 N/A
2 [] () . ++ -- 数组下标函数调用 & 构造函数结构体字段或方法选择器、交换后缀增量和减量 从左到右
3 ++ -- + - ! 前缀增量和减量一元 从右到左
4 * / 乘法和除法 从左到右
5 + - 加法和减法 从左到右
7 < > <= >= 关系 从左到右
8 == != 相等/不相等 从左到右
12 && 逻辑 AND 从左到右
13 ^^ 逻辑 XOR 从左到右
14 || 逻辑 OR 从左到右
15 ?\: 选择(一个完整的操作数) 从左到右
16 = += -= *= /= 赋值算术赋值算术赋值 从左到右
17 , 序列 从左到右

矩阵和向量运算

当应用于标量值时,算术运算符会产生一个标量。对于模运算符以外的运算符,如果一个操作数是标量,另一个操作数是向量或矩阵,则该运算将按组件执行并产生相同类型的向量或矩阵。如果两个操作数都是相同大小的向量,则该运算将按组件执行(并返回相同类型的向量)。

操作 描述
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(通用类型)是floatfloat2float3float4halfhalf2half3half4

大多数这些函数都是逐元素操作的(每个分量应用该函数)。在不是这种情况时会进行说明。

角度和三角函数

指定为角度的函数参数假定以弧度为单位。在任何情况下,这些函数都不会导致除以零错误。如果比率的除数为 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) 根据 x 的符号返回 -1.0、0.0 或 1.0
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) 返回夹在 minVal 和 maxVal 之间的 x。
GT clamp(GT x, float minVal, float maxVal) 返回夹在 minVal 和 maxVal 之间的 x
GT saturate(GT x) 返回夹在 0.0 和 1.0 之间的 x
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) 如果 x < edge,则返回 0.0,否则返回 1.0
GT step(float edge, GT x) 如果 x < edge,则返回 0.0,否则返回 1.0
GT smoothstep(GT edge0, GT edge1, GT x) 当 edge0 < x < edge1 时,执行 0 和 1 之间的 Hermite 插值
GT smoothstep(float edge0, float edge1, GT x) 当 edge0 < x < edge1 时,执行 0 和 1 之间的 Hermite 插值

几何函数

这些函数将向量作为向量进行操作,而不是逐元素操作。GT 是大小为 2-4 的 float/half 向量。

函数 描述
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) 如果 dot(Nref, I) < 0,则返回 N,否则返回 -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) 如果 x 的任何分量为true,则为true
bool all(BV x) 如果 x 的所有分量都为true,则为true
BV not(BV x) x 的逻辑补码

颜色函数

函数 描述
vec4 unpremul(vec4 color) 将颜色值转换为非预乘 alpha
half3 toLinearSrgb(half3 color) 颜色空间转换为线性 SRGB
half3 fromLinearSrgb(half3 color) 颜色空间转换

着色器采样(评估)

不支持采样器类型,但您可以评估其他着色器。如果您需要对纹理进行采样,您可以创建一个BitmapShader对象,并将其添加为统一变量。您可以对任何着色器执行此操作,这意味着您可以直接评估任何 Android 着色器,而无需先将其转换为Bitmap,包括其他RuntimeShader对象。这提供了极大的灵活性,但复杂的着色器评估起来可能很昂贵,尤其是在循环中。

uniform shader image;

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

原始缓冲区采样

尽管大多数图像包含应进行颜色管理的颜色,但某些图像包含并非真正颜色的数据,包括存储法线、材质属性(例如粗糙度)、高度图或任何其他碰巧存储在图像中的纯数学数据。在 AGSL 中使用此类图像时,您可以使用 BitmapShader 作为使用RuntimeShader#setInputBuffer的通用原始缓冲区。这将避免颜色空间转换和过滤。