AGSL と GLSL の違い

AGSL と GLSL は構文が非常に似ているため、多くの GLSL フラグメント シェーダー効果を、最小限の変更で Android に移植できます。AGSL は、GLSL 機能セットを GLSL ES 1.0(OpenGL ES 2.0 で使用されるシェーディング言語)に修正し、デバイスのリーチを最大化します。

GLSL フラグメント シェーダーは、ラスタライザとブレンディング ハードウェアの間の GPU の動作全体を制御します。このシェーダーは、色を計算するためのすべての処理を行い、生成された色がパイプラインのブレンディング ステージにフィードされます。AGSL でシェーダーを記述することは、Android グラフィック パイプラインのステージをプログラミングすることに相当します。言語の違いの多くは、この点に起因しています。

シェーダーの実行

GLSL シェーダーと同様に、AGSL シェーダーは main 関数で実行を開始します。GLSL とは異なり、この関数は「ローカル」座標でのシェーダーの位置をパラメータとして受け取ります。これは gl_FragCoord に似ていますが、フレームバッファの座標ではなく、シェーダーを呼び出す前にこれらの座標が変換されている可能性があります。その後、シェーダーはピクセル色を中精度または高精度の vec4 として返します(GLSL の out vec4 colorgl_FragColor と同様)。

mediump vec4 main(in vec2 fragCoord)

座標空間

GLSL と AGSL の座標空間

GLSL を使用して描画されるシェーダーと、AGSL を使用して描画されるほぼ同一のシェーダー

AGSL と GLSL は、デフォルトでは異なる座標空間を使用します。GLSL では、フラグメントの座標(fragCoord)は左下を基準とします。AGSL は Canvas の画面座標系と一致します。つまり、Y 軸は左上隅から始まります。必要に応じて、解像度を unform として渡し、Y 軸の値として resolution.y - fragCoord.y を使用することで、この 2 つの空間間の変換を行うことができます。また、ローカル変換行列をシェーダーに適用することもできます。

// 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 では、中程度の精度を表す half 型と short 型も導入されています。

ベクター型は <基本型><columns> という名前で宣言できます。vec2 の代わりに float2 を、bvec4 の代わりに bool4 を使用できます。行列型は <基本型><列>x<行> という名前で宣言できるため、mat3 ではなく float3x3 です。AGSL では、matvec の GLSL スタイルの宣言も許可されています。これらの型は対応する浮動小数点数にマッピングされます。

プリプロセッサ

AGSL は、GLSL スタイルのプリプロセッサ ディレクティブをサポートしていません。#define ステートメントを定数変数に変換します。AGSL のコンパイラは、定数変数の定数フォールディングと分岐除去をサポートしているため、これらが効率的です。

色空間

Android のアプリは色で管理されます。キャンバスの色空間は、描画の作業用色空間を決定します。ソース コンテンツ(BitmapShader などのシェーダーなど)にも色空間があります。

物理的に正確なライティングなどの特定の効果については、線形色空間で計算する必要があります。そのために、AGSL には次の組み込み関数が用意されています。

half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)

これらは、作業色空間と Android の LINEAR_EXTENDED_SRGB 色空間の間で色を変換します。この空間では、sRGB 色域と線形伝達関数が使用されます。拡張範囲値(0.0 未満および 1.0 超)を使用して sRGB 色域外の値を表現します。

ユニフォーム

AGSL では、ユニフォームに色が含まれているかどうかわからないため、色変換が自動的に適用されません。half4/float4/vec4layout(color) というラベルを付けます。これにより、制服が色に使用されることを 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())