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”精度 “int”范围
高音 \(\left\{-2^{62},2^{62}\right\}\) \(\left\{2^{-62},2^{62}\right\}\) 亲属: \(2^{-16}\) \(\left\{-2^{16},2^{16}\right\}\)
中等 \(\left\{-2^{14},2^{14}\right\}\) \(\left\{2^{-14},2^{14}\right\}\) 亲属: \(2^{-10}\) \(\left\{-2^{10},2^{10}\right\}\)
低腰 \(\left\{-2,2\right\}\) \(\left\{2^{-8},2\right\}\) 绝对值: \(2^{-8}\) \(\left\{-2^{8},2^{8}\right\}\)

除了数组数字下标语法之外,例如: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;

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

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

资格赛

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

变量声明

声明必须位于显式大括号范围内。以下示例中禁止声明 y

if (condition)
    int y = 0;

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

矩阵构造函数示例

使用单个值构造矩阵时,沿对角线的所有值都会指定该值,其余值则为零。因此,float2x2(1.0) 会创建一个 2x2 单位矩阵。

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

请注意,与 GLSL 不同,不支持减少传入矢量分量的构造函数,但您可以使用调配来达到相同的效果。如需基于 AGSL 中的 vec4 构造 vec3(其行为与 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 [] () . ++ -- 数组下标 函数调用和构造函数结构 字段或方法选择器 调配 后缀递增和递减 从左到右
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)

对于循环限制

与 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) 返回 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 < 边缘,则返回 0.0,否则返回 1.0
GT step(float edge, GT x) 如果 x < 边缘,则返回 0.0,否则返回 1.0
GT smoothstep(GT edge0, GT edge1, GT x) 当 Edge0 < x < Edge1 时,执行 0 到 1 之间的隐士插值
GT smoothstep(float edge0, float edge1, GT x) 当 Edge0 < x < Edge1 时,执行 0 到 1 之间的隐士插值

几何函数

这些函数将矢量作矢量,而非组成部分。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) 如果点(Nref, I) < 0,则返回 N,否则返回 -N。
GT reflect(GT I, GT N) 反射方向 I - 2 * 点(N,I) * N。
GT refract(GT I, GT N, float/half eta) 返回折射矢量

矩阵函数

Type 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 着色器,而无需先将其转换为位图,包括其他 RuntimeShader 对象。这可提供极大的灵活性,但复杂的着色器评估起来成本高昂,尤其是在循环中。

uniform shader image;

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

原始缓冲区采样

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