Perbedaan antara AGSL dan GLSL

AGSL dan GLSL sangat mirip dalam sintaksis, memungkinkan banyak efek shader fragmen GLSL dibawa ke Android dengan perubahan minimal. AGSL memperbaiki kumpulan fitur GLSL-nya 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 hardware pencampuran. Shader tersebut melakukan semua tugas untuk menghitung warna, dan warna yang dihasilkannya akan diberikan ke tahap pencampuran pipeline. Saat menulis shader di AGSL, Anda memprogram tahap pipeline grafis Android. Terdapat banyak perbedaan bahasa yang disebabkan oleh hal ini.

Eksekusi shader

Sama seperti di shader GLSL, shader AGSL memulai eksekusi dalam fungsi utama. Tidak seperti GLSL, fungsi ini menggunakan posisi shader dalam koordinat "lokal" sebagai parameter. Ini mirip dengan gl_FragCoord, tetapi bukan koordinat framebuffer, koordinat ini mungkin telah diterjemahkan sebelum memanggil shader Anda. Shader Anda kemudian menampilkan warna piksel sebagai vec4 dalam presisi sedang atau tinggi (mirip dengan out vec4 color atau gl_FragColor di GLSL).

mediump vec4 main(in vec2 fragCoord)

Ruang koordinat

Ruang koordinat GLSL vs AGSL

Shader digambar menggunakan GLSL vs Shader identik dekat yang digambar menggunakan AGSL

AGSL dan GLSL menggunakan ruang koordinat yang berbeda secara default. Dalam GLSL, koordinat fragmen (fragCoord) relatif terhadap kiri bawah. AGSL cocok dengan sistem koordinat layar Canvas, yang berarti sumbu Y dimulai dari sudut kiri atas. Jika perlu, Anda dapat melakukan konversi antara dua ruang ini dengan meneruskan resolusi sebagai seragam dan menggunakan resolution.y - fragCoord.y untuk nilai sumbu Y. Atau, Anda 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 mewakili 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>, sehingga float3x3, bukan mat3. AGSL juga mengizinkan deklarasi gaya GLSL untuk mat dan vec, dan jenis ini dipetakan ke float yang setara.

Praprosesor

AGSL tidak mendukung perintah preprocessor gaya GLSL. Mengonversi pernyataan #define menjadi variabel konstanta. Compiler AGSL mendukung folding konstan dan eliminasi cabang untuk variabel const, sehingga ini akan efisien.

Ruang warna

Aplikasi Android dikelola oleh warna. Ruang warna {i>Canvas<i} menentukan ruang warna kerja untuk menggambar. Konten sumber (seperti shader, termasuk BitmapShader) juga memiliki ruang warna.

Untuk efek tertentu, seperti pencahayaan yang akurat secara fisik, matematika harus dilakukan dalam ruang warna linear. Untuk membantu melakukan hal ini, AGSL menyediakan fungsi intrinsik berikut:

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

Keduanya mengonversi warna antara ruang warna yang berfungsi dan ruang warna LINEAR_EXTENDED_SRGB Android. Ruang tersebut menggunakan warna primer (gamut) sRGB dan fungsi transfer linear. Parameter ini mewakili nilai di luar gamut sRGB menggunakan nilai rentang yang diperluas (di bawah 0.0 dan di atas 1.0).

Seragam

Karena AGSL tidak tahu apakah seragam berisi warna, seragam tersebut tidak akan otomatis menerapkan konversi warna. Anda dapat melabeli half4/float4/vec4 dengan layout(color), yang memungkinkan Android mengetahui bahwa seragam akan digunakan sebagai warna, yang memungkinkan Android mengubah nilai seragam ke ruang warna yang berfungsi.

Di AGSL, deklarasikan seragam seperti ini:

layout(color) uniform half4 iColor;  // Input color
uniform float2 iResolution;          // Viewport resolution (pixels)

Dalam kode Android, Anda kemudian dapat menyetel seragam seperti ini:

shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())