Perbedaan antara AGSL dan GLSL

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

Ruang koordinat GLSL vs AGSL

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())