AGSL 與 GLSL 之間的差異

AGSL 和 GLSL 的語法非常相似,允許許多 GLSL 片段著色器 對 Android 的影響微乎其微AGSL 修正 GLSL 將功能設為 GLSL ES 1.0 (OpenGL ES 2.0 使用的陰影語言) 至 盡可能提高裝置觸及率

GLSL 片段著色器可控制 GPU 之間的整個行為 光柵地圖和混合硬體該著色器會負責計算 產生的顏色 剛好是混合圖中的顏色 管道組合使用 AGSL 編寫著色器時,就是設計出 Android 圖形管線很多語言差異都屬於這種情況。

著色器執行

就像 GLSL 著色器一樣,AGSL 著色器也會開始在主函式中執行。 與 GLSL 不同,函式會採用「local」的著色器位置視為 參數。這與 gl_FragCoord 類似,而非 framebuffer 座標,可能在呼叫 著色器。接著,著色器會將像素顏色傳回為 vec4 (中型或 高精確度 (與 GLSL 中的 out vec4 colorgl_FragColor 類似)。

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 已採用 halfshort 類型,也代表中等精確度。

向量類型可宣告為 <base type><columns>。別擔心!您可以使用 float2 而不是 vec2bool4 而不是 bvec4。 矩陣類型可宣告為 <base type><columns>x<rows>, float3x3 取代 mat3。AGSL 也允許 GLSL 樣式宣告 適用於 matvec,且這些類型會對應至其浮點值 相同。

預先處理器

AGSL 不支援 GLSL 樣式 預先處理器 指令將 #define 陳述式轉換為 const 變數。AGSL 編譯器 支援 const 變數的常數折疊和分支版本刪除功能,因此這些 更有效率

色域

Android 應用程式是由顏色管理。畫布的色彩空間會決定 就能執行繪圖的工作色彩空間來源內容 (例如著色器,包括 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())