AGSL e GLSL hanno una sintassi molto simile, pertanto molti effetti dell'shadowing dei frammenti GLSL vengono trasferiti su Android con modifiche minime. AGSL corregge il suo set di funzionalità GLSL su GLSL ES 1.0 (il linguaggio di ombreggiatura utilizzato da OpenGL ES 2.0) per garantire la massima copertura del dispositivo.
Uno shardr dei frammenti GLSL controlla l'intero comportamento della GPU tra il rasterizzatore e l'hardware di combinazione. Lo Shader si occupa di tutto per calcolare un colore, che genera esattamente quello che viene inviato alla fase di combinazione della pipeline. Quando scrivi uno shardr in AGSL, stai programmando una fase della pipeline grafica Android. Molte delle differenze linguistiche derivano da questo.
Esecuzione dello Shader
Proprio come in uno mesh GLSL, uno mesh AGSL inizia l'esecuzione in una funzione principale.
A differenza di GLSL, la funzione prende come parametro la posizione dello smoothr nelle coordinate "locali". È simile a gl_FragCoord
, ma al posto delle coordinate
del framebuffer potrebbero essere state tradotte prima di chiamare il tuo
shader. Loshadowr restituisce quindi il colore del pixel come vec4
con precisione media o elevata (simile a out vec4 color
o gl_FragColor
in GLSL).
mediump vec4 main(in vec2 fragCoord)
Spazio di coordinate
Ombreggiatura disegnata con GLSL e shader quasi identico disegnato con AGSL
AGSL e GLSL utilizzano spazi di coordinate diversi per impostazione predefinita. In GLSL, la coordinata
di frammento (fragCoord) è relativa a quella in basso a sinistra. AGSL corrisponde al sistema di coordinate dello schermo di Canvas, il che significa che l'asse Y inizia dall'angolo in alto a sinistra. Se necessario, puoi convertire tra questi due spazi passando la risoluzione come uniforme e utilizzando resolution.y - fragCoord.y
per il valore dell'asse Y. In alternativa, puoi applicare
una matrice di trasformazione locale al tuo meshr.
// AGSL to GLSL coordinate space transformation matrix
val localMatrix = Matrix()
localMatrix.postScale(1.0f, -1.0f)
localMatrix.postTranslate(0.0f, viewHeight)
gridShader.setLocalMatrix(localMatrix)
Precisione e tipi
Sono supportati i modificatori di precisione compatibili con GLSL, ma AGSL introduce i tipi half
e short
che rappresentano anche una precisione media.
I tipi vettoriali possono essere dichiarati come denominati <base type><columns>. Puoi usare
float2
anziché vec2
e bool4
anziché bvec4
.
I tipi di matrice possono essere dichiarati come denominati <tipo di base><columns>x<righe>, quindi
float3x3
anziché mat3
. AGSL consente inoltre dichiarazioni in stile GLSL per mat
e vec
e questi tipi sono mappati ai relativi equivalenti in virgola mobile.
Pre-elaboratore
AGSL non supporta le istruzioni per il preprocessore in stile GLSL. Converti le istruzioni #define in variabili const. Il compilatore AGSL supporta il ripiegamento costante e l'eliminazione dei rami per le variabili const, che saranno quindi efficienti.
Spazi colore
Le app Android sono gestite dai colori. Lo spazio colore di una Canvas determina lo spazio colore di lavoro per il disegno. Anche i contenuti di origine (come gli Shader, tra cui BitmapShader) hanno spazi colore.
Per alcuni effetti, come l'illuminazione accurata fisicamente, i calcoli matematici dovrebbero essere eseguiti in uno spazio colore lineare. Per aiutarti, AGSL fornisce queste funzioni intrinseche:
half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)
Queste conversioni convertono i colori tra lo spazio colore di lavoro e lo spazio dei colori LINEAR_EXTENDED_SRGB
di Android. Questo spazio utilizza i colori primari (gamut) sRGB e una funzione di trasferimento lineare. Rappresenta i valori al di fuori della gamma sRGB utilizzando valori di intervallo esteso (inferiori a 0,0 e superiori a 1,0).
Uniformi
Poiché AGSL non sa se le uniformi contengono colori, non le applica automaticamente una conversione dei colori. Puoi etichettare half4
/float4
/vec4
con
layout(color)
, che consente ad Android di sapere che l'uniforme verrà utilizzata come colore, consentendo ad Android di trasformare il valore uniforme in uno spazio colore
funzionante.
In AGSL, dichiara l'uniforme nel seguente modo:
layout(color) uniform half4 iColor; // Input color
uniform float2 iResolution; // Viewport resolution (pixels)
Nel codice Android, puoi quindi impostare l'uniforme in questo modo:
shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())