AGSL ve GLSL, söz dizimine çok benzerdir. Bu da, birçok GLSL parça gölgelendirici efektinin çok küçük değişikliklerle Android'e taşınmasına olanak tanır. AGSL, maksimum cihaz erişimi sağlamak için GLSL ES 1.0'da (OpenGL ES 2.0 tarafından kullanılan gölgelendirme dili) ayarlanan GLSL özelliğini düzeltir.
GLSL parça gölgelendirici, GPU'nun rastgeleleştirici ile karıştırma donanımı arasındaki tüm davranışını kontrol eder. Bu gölgelendirici, rengi hesaplamak için gereken tüm işi yapar ve oluşturduğu renk, tam olarak ardışık düzenin karıştırma aşamasına aktarılır. AGSL'de bir gölgelendirici yazdığınızda, Android grafik ardışık düzeninin bir aşamasını programlarsınız. Dil farklılıklarının çoğu bundan kaynaklanır.
Gölgelendirici yürütme
Bir GLSL gölgelendiricisinde olduğu gibi, AGSL gölgelendiricisi de bir ana işlevde yürütmeye başlar.
GLSL'nin aksine, işlev "yerel" koordinatlarında gölgelendirici konumunu parametre olarak alır. Bu gl_FragCoord
işlevine benzerdir ancak framebuffer koordinatları yerine bu koordinatlar gölgelendiriciniz çağrılmadan önce çevrilebilir. Daha sonra, gölgelendiriciniz piksel rengini orta veya yüksek hassasiyette vec4
olarak döndürür (GLSL'de out vec4 color
veya gl_FragColor
'ye benzer).
mediump vec4 main(in vec2 fragCoord)
Koordinat alanı
GLSL kullanılarak çizilmiş gölgelendirici ve AGSL kullanılarak çizilmiş neredeyse aynı gölgelendirici
AGSL ve GLSL, varsayılan olarak farklı koordinat boşlukları kullanır. GLSL'de parça koordinatı (fragCoord) sol alt koordinatla görelidir. AGSL, Canvas ekran koordinat sistemiyle eşleşir. Bu, Y ekseninin sol üst köşeden başladığı anlamına gelir. Gerekirse çözünürlüğü tek tip olarak geçirerek ve Y ekseni değeri için resolution.y - fragCoord.y
kullanarak bu iki boşluk arasında dönüşüm yapabilirsiniz. Alternatif olarak, gölgelendiricinize yerel bir dönüşüm matrisi uygulayabilirsiniz.
// AGSL to GLSL coordinate space transformation matrix
val localMatrix = Matrix()
localMatrix.postScale(1.0f, -1.0f)
localMatrix.postTranslate(0.0f, viewHeight)
gridShader.setLocalMatrix(localMatrix)
Hassasiyet ve türler
GLSL uyumlu hassasiyet değiştiriciler desteklenir ancak AGSL, orta hassasiyeti temsil eden half
ve short
türlerini sunar.
Vektör türleri, <base type><columns> olarak tanımlanabilir. vec2
yerine float2
ve bvec4
yerine bool4
kullanabilirsiniz.
Matris türleri, <base type><columns>x<rows> olarak tanımlanabilir. Dolayısıyla mat3
yerine float3x3
. AGSL, mat
ve vec
için GLSL stili bildirimlere de izin verir. Bu türler, kayan eşdeğerleriyle eşlenir.
Ön İşlemci
AGSL, GLSL stili ön işlemci yönergelerini desteklemez. #define ifadelerini sabit değişkenlere dönüştürün. AGSL'nin derleyicisi, değişken değişkenleri için sabit katlama ve dal gidermeyi desteklediğinden bu değişkenler verimli olur.
Renk alanları
Android Uygulamaları renklerle yönetilir. Bir Tuvalin renk alanı, çizim için çalışma renk alanını belirler. Kaynak içeriğin (BitmapShader dahil gölgelendiriciler gibi) renk alanları da vardır.
Fiziksel olarak doğru ışıklandırma gibi belirli efektler için matematik, doğrusal bir renk alanında gerçekleştirilmelidir. AGSL buna yardımcı olmak için şu içsel işlevleri sağlar:
half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)
Bunlar, renkleri çalışan renk alanı ile Android'in LINEAR_EXTENDED_SRGB
renk alanı arasında dönüştürür. Bu alan, sRGB renk primerlerini (gamut) ve bir doğrusal aktarım işlevini kullanır. Genişletilmiş aralık değerleri (0,0'ın altında ve 1,0'ın üzerinde) kullanarak sRGB gamının dışındaki değerleri temsil eder.
Üniformalar
AGSL, üniformaların renk içerip içermediğini bilmediği için bunlara otomatik olarak renk dönüştürmesi uygulamaz. half4
/float4
/vec4
etiketini layout(color)
etiketiyle etiketleyebilirsiniz. Böylece Android, tek tip değerin renk olarak kullanılacağını anlayabilir ve bu şekilde, tek tip değeri çalışan renk alanına dönüştürebilir.
AGSL'de, forma türünü şu şekilde belirtin:
layout(color) uniform half4 iColor; // Input color
uniform float2 iResolution; // Viewport resolution (pixels)
Android kodunda daha sonra tek tipliği şu şekilde ayarlayabilirsiniz:
shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())