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 {262,262} {262,262} 相对: 216 {216,216}
mediump {214,214} {214,214} 相对: 210 {210,210}
lowp {2,2} {28,2} 绝对值: 28 {28,28}

除了数组数字下标语法之外,例如 var[num], names of vector components for vectors of length 2 - 4 are denoted by a single letter. Components can be swizzled and replicated. ex: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 风格语法指定显式数组大小的一维数组:

<base type>[<array size>] 变量名称 - 例如:half[10] x;

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

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

资格赛

类型 说明
const 编译时常量或只读函数参数。
uniform 值在处理的每个基元中都不会发生变化。系统使用 RuntimeShader 方法针对 setColorUniformsetFloatUniformsetIntUniformsetInputBuffersetInputShader 从 Android 传递 uniform。
in 对于传入的函数参数。这是默认值。
out 对于传出的函数参数。必须使用与函数定义相同的精度。
inout 对于同时传入和传出函数的参数。必须使用与函数定义相同的精度。

变量声明

声明必须位于显式大括号作用域中。以下示例中 y 的声明不允许:

if (condition)
    int y = 0;

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

矩阵构造函数示例

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

使用多个值构建矩阵时,系统会先填充列(按列顺序)。

请注意,与 GLSL 不同,此语言不支持用于减少传入矢量组件数的构造函数,但您可以使用串联来实现相同的效果。如需在 AGSL 中根据 vec4 构造行为与 GLSL 相同的 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 () 括号分组 不适用
2 [] () . ++ -- 数组下标函数调用和构造函数结构字段或方法选择器、swizzle 后缀递增和递减 从左到右
3 ++ -- + - ! 前缀递增和递减运算符 - 一元运算符 从右到左
4 * / 乘法和除法 从左至右
5 + - 加减 从左至右
7 < > <= >= 关系型 从左至右
8 == != 等式/不等式 从左至右
12 && 逻辑与 从左至右
13 ^^ 逻辑 XOR 从左至右
14 || 逻辑或 从左至右
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 } - 默认情况下,最后一个是正例
跳跃 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 且在 [π2,π2] 范围内的角度
GT acos(GT x) 返回余弦值为 [0,π] 范围内的 x 的角度
GT atan(GT y, GT x) 返回一个角,其三角函数反正割值为 [yx],且在 [π,π] 范围内
GT atan(GT y_over_x) 返回一个角,其三角函数反正切值为 y_over_x,且在 [π2,π2] 范围内

指数函数

功能 说明
GT pow(GT x, GT y) 返回 xy
GT exp(GT x) 返回 ex
GT log(GT x) 返回 ln(x)
GT exp2(GT x) 返回 2x
GT log2(GT x) 返回 log2(x)
GT sqrt(GT x) 返回 x
GT inversesqrt(GT x) 返回 1x

常用函数

功能 说明
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) 返回将 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) 如果 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 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 中使用此类图片时,您可以使用 RuntimeShader#setInputBuffer 将 BitmapShader 用作通用原始缓冲区。这样可以避免色彩空间转换和滤除。