A AGSL foi projetada para ser amplamente compatível com a GLSL ES 1.0. Para mais informações, consulte a função equivalente na documentação da linguagem de sombreamento do OpenGL ES. Sempre que possível, esta documentação tenta destacar as diferenças entre AGSL e GLSL.
Tipos
A AGSL oferece suporte a tipos GLSL ES 1.0 e a uma maneira extra de representar tipos de vetor
e matriz. O AGSL oferece suporte a outros tipos de short
e half
para representar
precisão média.
Tipos básicos
Tipo | Descrição |
---|---|
void
|
Nenhum valor de retorno da função ou lista de parâmetros vazia. Ao contrário do GLSL, funções sem um tipo de retorno vazio precisam retornar um valor. |
bool, bvec2, bvec3, bvec4 (bool2, bool3, bool4) . |
Escalar/vetor booleano |
int, ivec2, ivec3, ivec4 (int2, int3, int4) |
highp número inteiro/vetor assinado
|
float, vec2, vec3, vec4 (float2, float3, float4)
|
highp (precisão simples) ponto flutuante
escalar/vetor |
short, short2, short3, short4
|
equivalente a um número
inteiro/vetor assinado mediump int |
half, half2, half3, half4 |
equivalente a mediump float escalar/vetor |
mat2, mat3, mat4 (float2x2, float3x3, float4x4) |
Matriz float de 2x2, 3x3 e 4x4
|
half2x2, half3x3, half4x4 |
Equivalente aos tipos de matriz mediump float |
Precisão e intervalos mínimos
Estes são a precisão e o intervalo mínimos garantidos associados a cada
modificador com base na especificação OpenGL ES 2.0. Como a maioria dos dispositivos
oferece suporte ao ES 3.0, eles terão mais precisão/intervalo highp
e
intervalo int mediump
garantidos. Os modificadores de precisão podem ser aplicados a variáveis e parâmetros escalares,
vetoriais e de matriz. Somente os mínimos listados abaixo são garantidos.
lowp
não tem necessariamente menor precisão do que mediump
, e mediump
não tem necessariamente menor precisão do que highp
. No momento, o AGSL converte lowp
em mediump
na saída final.
Modificador | Intervalo de "float" | Intervalo de magnitude de "float" | Precisão de "float" | Intervalo de "int" |
---|---|---|---|---|
highp | \(\left\{-2^{62},2^{62}\right\}\) | \(\left\{2^{-62},2^{62}\right\}\) | Parente: \(2^{-16}\) | \(\left\{-2^{16},2^{16}\right\}\) |
mediump | \(\left\{-2^{14},2^{14}\right\}\) | \(\left\{2^{-14},2^{14}\right\}\) | Parente: \(2^{-10}\) | \(\left\{-2^{10},2^{10}\right\}\) |
lowp | \(\left\{-2,2\right\}\) | \(\left\{2^{-8},2\right\}\) | Absoluto: \(2^{-8}\) | \(\left\{-2^{8},2^{8}\right\}\) |
Além da sintaxe de subscripto numérico de matriz, por exemplo: var[num], names of vector
components for vectors of length 2 - 4 are denoted by a single letter. Components
can be swizzled and replicated. ex:
vect.yx,
vect.yy`
vect.xyzw
: use ao acessar vetores que representam pontos/normais.
vect.rgba
: use ao acessar vetores que representam cores.
vect.LTRB
: use quando o vetor representa um retângulo (não no GLSL)
Na AGSL, 0 e 1 podem ser usados para produzir uma constante 0 ou 1 nesse canal.
Exemplo: vect.rgb1 == vec4(vect.rgb,1)
Estruturas e matrizes
As estruturas são declaradas com a mesma sintaxe do GLSL, mas o AGSL só oferece suporte a estruturas no escopo global.
struct type-name {
members
} struct-name; // optional variable declaration.
Somente matrizes unidimensionais são compatíveis com um tamanho de matriz explícito, usando a sintaxe do estilo C ou GLSL:
<base type>[<array size>] nome da variável - ex: half[10] x;
<base type> nome da variável [<array size>] - ex: half x[10];
Matrizes não podem ser retornadas de uma função, copiadas, atribuídas ou comparadas. As restrições de matrizes se propagam para estruturas que contêm matrizes. As matrizes só podem ser indexadas usando uma constante ou uma variável de loop.
Qualificatórias
Tipo | Descrição |
---|---|
const
|
Constante de tempo de compilação ou parâmetro de função somente leitura. |
uniform
|
O valor não muda na primitiva
que está sendo processada.
Os uniformes são transmitidos do Android usando
métodos RuntimeShader
para setColorUniform , setFloatUniform ,
setIntUniform , setInputBuffer e
setInputShader . |
in
|
Para parâmetros de função transmitidos. Esse é o padrão. |
out
|
Para parâmetros de função transmitidos. Precisa usar a mesma precisão da definição da função. |
inout
|
Para parâmetros transmitidos para dentro e fora de uma função. Precisa usar a mesma precisão da definição da função. |
Declaração de variável
As declarações precisam estar em um escopo explícito entre chaves. A declaração de y
no
exemplo a seguir não é permitida:
if (condition)
int y = 0;
Conceitos básicos de matriz/estrutura/vetor
Exemplos de construtor de matriz
Quando uma matriz é construída com um único valor, todos os valores ao longo
da diagonal recebem esse valor, enquanto o restante recebe zeros. float2x2(1.0)
, portanto,
cria uma matriz de identidade 2x2.
Quando uma matriz é construída com vários valores, as colunas são preenchidas primeiro (ordem de colunas principais).
Ao contrário do GLSL, não há suporte para construtores que reduzem o número de componentes de um
vetor transmitido, mas você pode usar o swizzling para ter o mesmo
efeito. Para construir um vec3
de um vec4
na AGSL com o mesmo comportamento da
GLSL, especifique vec3 nv = quadVec.xyz
.
Exemplo de construtor de estrutura
struct light { float intensity; float3 pos; };
// literal integer constants auto-converted to floating point
light lightVar = light(3, float3(1, 2, 3.0));
Componentes da matriz
Acesse os componentes de uma matriz com a sintaxe de subscrito de matriz.
float4x4 m; // represents a matrix
m[1] = float4(2.0); // sets second column to all 2.0
m[0][0] = 1.0; // sets upper left element to 1.0
m[2][3] = 2.0; // sets 4th element of 3rd column to 2.0
Campos de estrutura
Selecione campos de estrutura usando o operador de período .
. Os operadores incluem:
Operador | Descrição |
---|---|
. |
seletor de campo |
==, != |
igualdade |
= |
atribuição |
Elementos de matriz
Os elementos de matriz são acessados usando o operador de subscrito de matriz [ ]
. Exemplo:
diffuseColor += lightIntensity[3] * NdotL;
Operadores
Numeradas em ordem de precedência. Os operadores relacionais e de igualdade > < <= >= == != são avaliados como booleanos. Para comparar vetores
por componente, use funções como lessThan()
, equal()
etc.
Operador | Descrição | Associatividade | |
---|---|---|---|
1 | () |
agrupamento entre parênteses | N/A |
2 | [] () . ++ --
|
Chamada de função de subscrito de matriz e seletor de campo ou método de estrutura do construtor, incremento pós-fixo e decremento de swizzle | Da esquerda para a direita |
3 | ++ -- + - !
|
prefixo incremento e decremento unário | Da direita para a esquerda |
4 | * / |
multiplicar e dividir | Da esquerda para a direita |
5 | + - |
somar e subtrair | Da esquerda para a direita |
7 | < > <= >= |
relacional | Da esquerda para a direita |
8 | == != |
igualdade/desigualdade | Da esquerda para a direita |
12 | && |
lógico AND | Da esquerda para a direita |
13 | ^^ |
XOR lógico | Da esquerda para a direita |
14 | || |
OR lógico | Da esquerda para a direita |
15 | ?\:
|
seleção (um operando inteiro) | Da esquerda para a direita |
16 | = += -= *= /=
|
atribuição atribuição aritmética atribuição aritmética | Da esquerda para a direita |
17 | , |
sequência | Da esquerda para a direita |
Operações de matriz e vetor
Quando aplicados a valores escalares, os operadores aritméticos resultam em um escalar. Para operadores que não sejam módulo, se um operando for um escalar e o outro for um vetor ou matriz, a operação será realizada de forma componente e resultará no mesmo tipo de vetor ou matriz. Se as duas operações forem vetores do mesmo tamanho, a operação será realizada de forma componente (e retornará o mesmo tipo de vetor).
Operação | Descrição |
---|---|
m = f * m |
Multiplicação de matrizes por componente por um valor escalar |
v = f * v |
Multiplicação de vetor por componente por um valor escalar |
v = v * v |
Multiplicação de vetores por componente por um valor de vetor |
m = m + m |
Adição por componente de matriz |
m = m - m |
Subtração por componente de matriz |
m = m * m |
Multiplicação algébrica linear |
Se um operando for um vetor que corresponde ao tamanho da linha ou da coluna da matriz, o operador de multiplicação poderá ser usado para fazer multiplicação algébrica de linhas e colunas.
Operação | Descrição |
---|---|
m = v * m |
Vetor de linha * multiplicação algébrica linear de matriz |
m = m * v |
Matriz * multiplicação algébrica linear do vetor de coluna |
Use as funções integradas para produto escalar vetorial, produto vetorial e multiplicação por componente:
Função | Descrição |
---|---|
f = dot(v, v) |
Produto escalar de vetores |
v = cross(v, v) |
Produto vetorial |
m = matrixCompMult(m, m) |
Multiplicação por componente |
Controle do programa
Chamada de função | Chamada por retorno de valor |
---|---|
Iteração | for (<init>;<test>;<next>) { break, continue } |
Seleção | if ( ) { } if ( ) { } else { } switch () { break, case }
- caso padrão por último |
Pular | break, continue, return (descartar não é permitido) |
Entrada | half4 main(float2 fragCoord) |
Limitações de repetição for
Semelhante ao GLSL ES 1.0, os loops "for" são bastante limitados. O compilador precisa ser capaz
de desenrolar o loop. Isso significa que o inicializador, a condição de teste e a
instrução next
precisam usar constantes para que tudo possa ser computado no momento da
compilação. A instrução next
é limitada ao uso de ++, --, +=, or -=
.
Funções integradas
GT
(tipo genérico) é float
, float2
, float3
, float4
ou
half
, half2
, half3
, half4
.
A maioria dessas funções opera por componente (a função é aplicada por componente). Isso é registrado quando não é o caso.
Ângulo e funções trigonométricas
Os parâmetros de função especificados como um ângulo são considerados em unidades de radianos. Nenhuma dessas funções resulta em um erro de divisão por zero. Se o divisor de uma proporção for 0, os resultados serão indefinidos.
Função | Descrição |
---|---|
GT radians(GT degrees) |
Converte graus em radianos |
GT degrees(GT radians) |
Converte radianos em graus |
GT sin(GT angle) |
Senóide padrão |
GT cos(GT angle) |
Cosseno padrão |
GT tan(GT angle) |
Tangente padrão |
GT asin(GT x)
|
Retorna um ângulo cujo seno é x no intervalo de $ \left[-{\pi\over 2},{\pi\over 2}\right] $ |
GT acos(GT x)
|
Retorna um ângulo cujo cosseno é x no intervalo de $ \left[0,\pi\right] $ |
GT atan(GT y, GT x)
|
Retorna um ângulo em que o arcotangente trigonométrico é $ \left[{y\over x}\right] $ no intervalo de $ \left[-\pi,\pi\right] $ |
GT atan(GT y_over_x)
|
Retorna um ângulo em que a arcotangente
trigonômica é y_over_x no intervalo
de $ \left[-{\pi\over 2},{\pi\over 2}\right] $ |
Funções exponenciais
Função | Descrição |
---|---|
GT pow(GT x, GT y) |
Retorna $ x^y $ |
GT exp(GT x) |
Retorna $ e^x $ |
GT log(GT x) |
Retorna $ ln(x) $ |
GT exp2(GT x) |
Retorna $ 2^x $ |
GT log2(GT x) |
Retorna $ log_2(x) $ |
GT sqrt(GT x) |
Retorna $ \sqrt{x} $ |
GT inversesqrt(GT x) |
Retorna $ 1\over{\sqrt{x}} $ |
Funções comuns
Função | Descrição |
---|---|
GT abs(GT x) |
Valor absoluto |
GT sign(GT x) |
Retorna -1,0, 0,0 ou 1,0 com base no sinal de x |
GT floor(GT x) |
Número inteiro mais próximo <= x |
GT ceil(GT x) |
Número inteiro mais próximo >= x |
GT fract(GT x) |
Retorna a parte fracionária de x |
GT mod(GT x, GT y) |
Retorna o valor de x módulo y |
GT mod(GT x, float y) |
Retorna o valor de x módulo y |
GT min(GT x, GT y) |
Retorna o valor mínimo de x ou y |
GT min(GT x, float y) |
Retorna o valor mínimo de x ou y |
GT max(GT x, GT y) |
Retorna o valor máximo de x ou y |
GT max(GT x, float y) |
Retorna o valor máximo de x ou y |
GT clamp(GT x, GT
minVal, GT maxVal) |
Retorna x limitado entre minVal e maxVal. |
GT clamp(GT x, float
minVal, float maxVal) |
Retorna x limitado entre minVal e maxVal |
GT saturate(GT x) |
Retorna x limitado entre 0,0 e 1,0. |
GT mix(GT x, GT y,
GT a) |
Retorna a mistura linear de x e y |
GT mix(GT x, GT y,
float a) |
Retorna a mistura linear de x e y |
GT step(GT edge, GT x) |
Retorna 0,0 se x < borda, caso contrário, 1,0 |
GT step(float edge,
GT x) |
Retorna 0,0 se x < borda, caso contrário, 1,0 |
GT smoothstep(GT edge0,
GT edge1, GT x) |
Realiza a interpolação de Hermite entre 0 e 1 quando edge0 < x < edge1 |
GT smoothstep(float
edge0, float edge1,
GT x) |
Realiza a interpolação de Hermite entre 0 e 1 quando edge0 < x < edge1 |
Funções geométricas
Essas funções operam em vetores como vetores, não por componentes. O GT é um vetor flutuante/meio nos tamanhos 2 a 4.
Função | Descrição |
---|---|
float/half length
(GT x) |
Retorna o comprimento do vetor |
float/half distance(GT
p0, GT p1) |
Retorna a distância entre pontos |
float/half dot(GT x,
GT y) |
Retorna o produto escalar |
float3/half3
cross(float3/half3 x,
float3/half3 y) |
Retorna o produto cruzado |
GT normalize(GT x) |
Normalizar o vetor para comprimento 1 |
GT faceforward(GT N,
GT I, GT Nref) |
Retorna N se dot(Nref, I) < 0, caso contrário, -N. |
GT reflect(GT I, GT N) |
Direção de reflexão I - 2 * dot(N,I) * N. |
GT refract(GT I, GT N,
float/half eta) |
Retorna o vetor de refração |
Funções de matriz
O tipo mat é qualquer tipo de matriz quadrada.
Função | Descrição |
---|---|
mat matrixCompMult(mat
x, mat y) |
Multiplicar x por y componente por componente |
mat inverse(mat m) |
Retorna o inverso de m |
Funções relacionais de vetores
Compare os componentes x e y. Os tamanhos dos vetores de entrada e retorno de uma chamada específica precisam ser iguais. T é a união de tipos de vetor de ponto flutuante e inteiro. O BV é um vetor booleano que corresponde ao tamanho dos vetores de entrada.
Função | Descrição |
---|---|
BV lessThan(T x, T y) |
x < y |
BV lessThanEqual(T x,
T y) |
x <= y |
BV greaterThan(T x,
T y) |
x > y |
BV greaterThanEqual(T
x, T y) |
x >= y |
BV equal(T x, T y) |
x == y |
BV equal(BV x, BV y) |
x == y |
BV notEqual(T x, T y) |
x != y |
BV notEqual(BV x,
BV y) |
x != y |
bool any(BV x) |
true se qualquer componente de x for true |
bool all(BV x) |
true se todos os componentes de x forem true . |
BV not(BV x) |
complemento lógico de x |
Funções de cor
Função | Descrição |
---|---|
vec4 unpremul(vec4
color) |
Converte o valor da cor em alfa não pré-multiplicado |
half3 toLinearSrgb(half3
color) |
Transformação do espaço de cores em sRGB linear |
half3 fromLinearSrgb(half3
color) |
Transformação do espaço de cores |
Amostragem de sombreador (avaliação)
Os tipos de amostrador não são compatíveis, mas você pode avaliar outros shaders. Se você precisar de amostrar uma textura, crie um objeto BitmapShader e adicione-o como um uniforme. Isso pode ser feito para qualquer sombreador, o que significa que é possível avaliar diretamente qualquer sombreador do Android sem transformá-lo em um Bitmap primeiro, incluindo outros objetos RuntimeShader. Isso permite uma grande quantidade de flexibilidade, mas shaders complexos podem ser caros para avaliar, principalmente em um loop.
uniform shader image;
image.eval(coord).a // The alpha channel from the evaluated image shader
Amostragem de buffer bruto
Embora a maioria das imagens contenha cores que precisam ser gerenciadas, algumas imagens contêm dados que não são cores, incluindo imagens que armazenam normais, propriedades de material (por exemplo, rugosidade), mapas de altura ou qualquer outro dado puramente matemático que seja armazenado em uma imagem. Ao usar esses tipos de imagens na AGSL, é possível usar um BitmapShader como um buffer bruto genérico usando RuntimeShader#setInputBuffer. Isso evita transformações e filtragem do espaço de cores.