A sintaxe da AGSL e da GLSL é muito parecida, permitindo que muitos sombreadores de fragmento do GLSL para o Android com pequenas alterações. AGSL corrige GLSL definido em GLSL ES 1.0 (a linguagem de sombreamento usada pelo OpenGL ES 2.0) para fornecem o alcance máximo do dispositivo.
Um sombreador de fragmento GLSL controla todo o comportamento da GPU entre as e o hardware de combinação. Esse shader faz todo o trabalho para calcular um cor, e a cor gerada é exatamente o que é fornecido à fase de mistura do pipeline. Ao escrever um shader na AGSL, você programa uma etapa de o pipeline de gráficos do Android. Muitas das diferenças linguísticas são provenientes disso.
Execução de sombreador
Assim como em um sombreador GLSL, um sombreador da AGSL começa a execução em uma função principal.
Ao contrário da GLSL, a função pega a posição do sombreador em "local" coordenadas como uma
. Isso é semelhante a gl_FragCoord
, mas em vez de framebuffer.
coordenadas, essas coordenadas podem ter sido traduzidas antes de chamar sua função
sombreador. Em seguida, o shader retorna a cor do pixel como um vec4
em valor médio ou
alta precisão (semelhante a out vec4 color
ou gl_FragColor
em GLSL);
mediump vec4 main(in vec2 fragCoord)
Espaço de coordenadas
Sobredor desenhado usando GLSL x sombreador quase idêntico desenhado usando AGSL
Por padrão, a AGSL e a GLSL usam espaços de coordenadas diferentes. Em GLSL, o fragmento
a coordenada (fragCoord) é relativa à parte inferior esquerda. A AGSL corresponde à tela
Sistema de coordenadas do Canvas,
o que significa que o eixo Y começa no canto superior esquerdo. Se necessário,
podem converter entre esses dois espaços transmitindo a resolução como uma
e usando resolution.y - fragCoord.y
como o valor do eixo Y. Você também pode
pode aplicar uma matriz de transformação local ao 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)
Precisão e tipos
Modificadores de precisão compatíveis com GLSL são compatíveis, mas a AGSL introduz
Tipos half
e short
, que também representam a precisão média.
Os tipos de vetor podem ser declarados como <base type><columns>. Você pode usar
float2
em vez de vec2
e bool4
em vez de bvec4
.
Os tipos de matriz podem ser declarados como <base type><columns>x<rows>, portanto,
float3x3
em vez de mat3
. A AGSL também permite declarações no estilo GLSL
para mat
e vec
, e esses tipos são mapeados para os respectivos pontos flutuantes.
equivalentes.
Pré-processador
A AGSL não oferece suporte ao estilo GLSL pré-processador diretivas. Converter instruções #define em variáveis constantes. Compilador da AGSL oferece suporte a dobras constantes e eliminação de ramificações para constantes de variáveis, de modo que essas será eficiente.
Espaços de cor
Os aplicativos Android são gerenciados por cores. O espaço de cores de uma tela determina o espaço de cores de trabalho para desenhar. Conteúdo de origem (como sombreadores, incluindo BitmapShader). também têm espaços de cor.
Para alguns efeitos, como iluminação física e física, é preciso fazer cálculos em um espaço de cores linear. Para ajudar com isso, a AGSL oferece estas soluções funções:
half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)
Eles convertem cores entre o espaço de cores de trabalho e o
LINEAR_EXTENDED_SRGB
espaço de cores. Esse espaço usa cores primárias sRGB (gamut) e um
função de transferência. Ela representa valores fora da gama sRGB usando
(abaixo de 0,0 e acima de 1,0).
Uniformes
Como a AGSL não sabe se os uniformes contêm cores, ela não aplica automaticamente
uma conversão de cor. Você pode marcar half4
/float4
/vec4
com
layout(color)
, que informa ao Android que o uniforme será usado como
cor, permitindo que o Android transforme o valor uniforme na cor de trabalho
espaço.
Na AGSL, declare o uniforme assim:
layout(color) uniform half4 iColor; // Input color
uniform float2 iResolution; // Viewport resolution (pixels)
No código do Android, você pode definir o uniforme desta forma:
shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())