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' 精確度 '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], 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 傳遞均勻色塊。
in 針對傳入的函式參數。此為預設值。
out 針對已傳出的函式參數。必須使用與函式定義相同的運算精確度。
inout 適用於同時傳入函式和傳出函式的參數。必須使用與函式定義相同的精確度。

變數宣告

宣告必須位於明確的括號範圍內。以下範例中 y 的宣告不允許:

if (condition)
    int y = 0;

矩陣/結構體/陣列的基本概念

矩陣建構函式範例

當矩陣以單一值建構時,對角線上的所有值都會設為該值,而其餘的值則設為零。因此,float2x2(1.0) 會建立 2x2 的單位矩陣。

矩陣使用多個值建構時,系統會先填入資料欄 (以資料欄為主)。

請注意,與 GLSL 不同,此函式不支援可減少傳入向量元件數量的建構函式,但您可以使用 swizzling 取得相同效果。如要從 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 [] () . ++ -- 陣列運算子函式呼叫與建構函式結構欄位或方法選取器、Swizzle 後置字首遞增和遞減 由左至右
3 ++ -- + - ! 前置字元遞增和遞減 unary 由右至左
4 * / 乘法和除法 從左至右
5 + - 加法和減法 從左至右
7 < > <= >= 關聯式 從左至右
8 == != 相等/不等 從左至右
12 && 邏輯 AND 從左至右
13 ^^ 邏輯 XOR 從左至右
14 || 邏輯 OR 從左至右
15 ?\: 選取項目 (一個完整運算元) 由左至右
16 = += -= *= /= assignment arithmetic assignment arithmetic assignment 從左到右
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 } - 預設為最後一個案例
Jump 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) 傳回 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) true,如果 x 的任何元件為 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 用作一般原始緩衝區。這樣可避免色彩空間轉換和篩選。