Diferencias entre AGSL y GLSL

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

Espacios de coordenadas de GLSL y AGSL

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