Diferenças entre AGSL e GLSL

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

Espaços de coordenadas GLSL vs. AGSL

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