AGSL dan GLSL sangat mirip dalam sintaksis, memungkinkan banyak shader fragmen GLSL yang akan dibawa ke Android dengan perubahan minimal. AGSL memperbaiki GLSL-nya set fitur pada GLSL ES 1.0 (bahasa shading yang digunakan oleh OpenGL ES 2.0) untuk menyediakan jangkauan perangkat maksimum.
Shader fragmen GLSL mengontrol seluruh perilaku GPU antara rasterizer dan perangkat keras pencampur. Shader itu melakukan semua pekerjaan untuk menghitung warna, dan warna yang dihasilkannya adalah apa yang dimasukkan ke tahap penggabungan dari pipeline. Ketika Anda menulis shader dalam AGSL, Anda memprogram tahap pipeline grafis Android. Banyak perbedaan bahasa disebabkan oleh hal ini.
Eksekusi shader
Sama seperti dalam shader GLSL, shader AGSL memulai eksekusi dalam fungsi utama.
Tidak seperti GLSL, fungsi ini mengambil posisi shader di "local" sebagai
. Ini mirip dengan gl_FragCoord
, tetapi bukan framebuffer
koordinat ini, koordinat ini mungkin telah diterjemahkan sebelum memanggil
shader. Shader Anda kemudian menampilkan warna piksel sebagai vec4
dalam warna sedang atau
presisi tinggi (mirip dengan out vec4 color
atau gl_FragColor
dalam GLSL).
mediump vec4 main(in vec2 fragCoord)
Ruang koordinat
Shader digambar menggunakan GLSL vs. Shader identik yang dibuat menggunakan AGSL
AGSL dan GLSL menggunakan ruang koordinat yang berbeda secara default. Dalam GLSL, fragmen
koordinat (fragCoord) relatif terhadap sudut kiri bawah. AGSL cocok dengan layar
sistem koordinat Canvas,
yang berarti bahwa sumbu Y dimulai
dari sudut kiri atas. Jika diperlukan, Anda
bisa mengonversi di antara kedua spasi ini dengan meneruskan resolusi sebagai
dan menggunakan resolution.y - fragCoord.y
untuk nilai sumbu Y. Atau, Anda dapat
dapat menerapkan matriks transformasi lokal ke shader.
// AGSL to GLSL coordinate space transformation matrix
val localMatrix = Matrix()
localMatrix.postScale(1.0f, -1.0f)
localMatrix.postTranslate(0.0f, viewHeight)
gridShader.setLocalMatrix(localMatrix)
Presisi dan jenis
Pengubah presisi yang kompatibel dengan GLSL didukung, tetapi AGSL memperkenalkan
Jenis half
dan short
yang juga menampilkan presisi sedang.
Jenis vektor dapat dideklarasikan sebagai bernama <base type><columns>. Anda dapat menggunakan
float2
, bukan vec2
, dan bool4
, bukan bvec4
.
Jenis matriks dapat dideklarasikan sebagai bernama <base type><columns>x<rows>, jadi
float3x3
, bukan mat3
. AGSL juga memungkinkan deklarasi gaya GLSL
untuk mat
dan vec
, serta jenis ini dipetakan ke float
padanannya.
Praprosesor
AGSL tidak mendukung gaya GLSL praprosesor direktif. Mengonversi pernyataan #define menjadi variabel konstanta. Compiler AGSL mendukung pelipatan konstan dan penghapusan cabang untuk variabel konst, jadi akan menjadi efisien.
Ruang warna
Aplikasi Android dikelola warna. Ruang warna {i>Canvas<i} menentukan ruang warna yang bekerja untuk menggambar. Konten sumber (seperti shader, termasuk BitmapShader) juga memiliki ruang warna.
Untuk efek tertentu, seperti pencahayaan yang akurat secara fisik, penghitungan harus dilakukan dalam ruang warna linear. Untuk membantu hal ini, AGSL menyediakan komponen fungsi-fungsi:
half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)
Ini mengonversi warna antara ruang warna yang berfungsi dan
LINEAR_EXTENDED_SRGB
ruang warna. Ruang itu menggunakan warna primer sRGB (gamut), dan
fungsi transfer data. Merepresentasikan nilai di luar gamut sRGB menggunakan perluasan
rentang nilai (di bawah 0,0 dan di atas 1,0).
Seragam
Karena AGSL tidak mengetahui apakah seragam berisi warna, AGSL tidak akan diterapkan secara otomatis
konversi warna
ke mereka. Anda dapat memberi label half4
/float4
/vec4
dengan
layout(color)
, yang memberi tahu Android bahwa uniform akan digunakan sebagai
warna, yang memungkinkan Android mengubah nilai seragam menjadi warna yang berfungsi
spasi.
Dalam AGSL, deklarasikan uniform seperti ini:
layout(color) uniform half4 iColor; // Input color
uniform float2 iResolution; // Viewport resolution (pixels)
Dalam kode Android, Anda kemudian dapat menyetel uniform seperti ini:
shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())