AGSL y GLSL tienen una sintaxis muy similar, lo que permite que se incorporen muchos efectos de sombreador de fragmentos GLSL a Android con cambios mínimos. AGSL corrige su conjunto de atributos GLSL en GLSL ES 1.0 (el lenguaje de sombreado que usa OpenGL ES 2.0) para proporcionar el máximo alcance del dispositivo.
Un sombreador de fragmentos GLSL controla todo el comportamiento de la GPU entre el radar y el hardware de combinación. Ese sombreador hace todo el trabajo para procesar un color, y el color que genera es el que se envía a la etapa de combinación de la canalización. Cuando escribes un sombreador en AGSL, programas una etapa de la canalización de gráficos de Android. Muchas de las diferencias de idioma surgen de esto.
Ejecución de sombreador
Al igual que en un sombreador GLSL, un sombreador AGSL comienza la ejecución en una función principal.
A diferencia de GLSL, la función toma la posición del sombreador en coordenadas "locales" como parámetro. Es similar a gl_FragCoord
, pero, en lugar de las coordenadas del búfer de fotogramas, es posible que estas coordenadas se hayan traducido antes de llamar al sombreador. Luego, el sombreador mostrará el color de píxeles como un vec4
en precisión media o alta (similar a out vec4 color
o gl_FragColor
en GLSL).
mediump vec4 main(in vec2 fragCoord)
Espacio de coordenadas
Sombreador dibujado con GLSL frente a sombreador casi idéntico dibujado con AGSL
AGSL y GLSL usan diferentes espacios de coordenadas de forma predeterminada. En GLSL, la coordenada del fragmento (fragCoord) es relativa a la parte inferior izquierda. AGSL coincide con el sistema de coordenadas de pantalla de Canvas, lo que significa que el eje Y comienza desde la esquina superior izquierda. Si es necesario, puedes realizar una conversión entre estos dos espacios pasando la resolución de manera uniforme y usando resolution.y - fragCoord.y
para el valor del eje Y. Como alternativa, puedes aplicar una matriz de transformación local al sombreador.
// AGSL to GLSL coordinate space transformation matrix
val localMatrix = Matrix()
localMatrix.postScale(1.0f, -1.0f)
localMatrix.postTranslate(0.0f, viewHeight)
gridShader.setLocalMatrix(localMatrix)
Precisión y tipos
Se admiten los modificadores de precisión compatibles con GLSL, pero AGSL introduce los tipos half
y short
, que también representan la precisión media.
Los tipos de vectores se pueden declarar como <base type><columns>. Puedes usar float2
en lugar de vec2
y bool4
en lugar de bvec4
.
Los tipos de matriz se pueden declarar como <base type><columns>x<rows>, por lo que float3x3
en lugar de mat3
. AGSL también permite declaraciones de estilo GLSL para mat
y vec
, y estos tipos se asignan a sus equivalentes de número de punto flotante.
Preprocesador
AGSL no admite las directivas del preprocesador de estilo GLSL. Convierte declaraciones #define en variables const. El compilador de AGSL admite el plegado constante y la eliminación de ramas para variables const, por lo que serán eficientes.
Espacios de color
Las aplicaciones para Android se administran por color. El espacio de color de un lienzo determina el espacio de color en funcionamiento para dibujar. El contenido de origen (como sombreadores, incluido BitmapShader) también tiene espacios de color.
Para ciertos efectos, como la iluminación física precisa, las operaciones matemáticas deben realizarse en un espacio de color lineal. Para ayudar con esto, AGSL proporciona estas funciones intrínsecas:
half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)
Estos convierten los colores entre el espacio de color de trabajo y el espacio de color LINEAR_EXTENDED_SRGB
de Android. Ese espacio usa los colores primarios sRGB (gamut) y una función de transferencia lineal. Representa valores fuera de la gama sRGB mediante valores de rango extendido (inferiores a 0.0 y superiores a 1.0).
Uniformes
Como AGSL no sabe si los uniformes contienen colores, no aplicará automáticamente una conversión de color. Puedes etiquetar half4
, float4
y vec4
con layout(color)
, lo que le indica a Android que el uniforme se usará como color, lo que le permite a Android transformar el valor uniforme en el espacio de color de trabajo.
En AGSL, declara el uniforme de la siguiente manera:
layout(color) uniform half4 iColor; // Input color
uniform float2 iResolution; // Viewport resolution (pixels)
En el código de Android, puedes configurar el uniforme de la siguiente manera:
shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())