A AGSL foi projetada para ser amplamente compatível com a GLSL ES 1.0. Para saber mais, consulte a função equivalente na documentação da linguagem de sombreador do OpenGL ES. Quando possível, esta documentação tenta destacar as diferenças entre AGSL e GLSL.
Tipos
A AGSL oferece suporte aos tipos GLSL ES 1.0, além de uma outra maneira de representar tipos de
vetor e matriz. A AGSL é compatível com outros tipos de short
e half
para representar a precisão média.
Tipos básicos
Tipo | Descrição |
---|---|
void
|
Nenhum valor de retorno de função ou lista de parâmetros vazia. Ao contrário da GLSL, as funções sem um tipo de retorno nulo precisam retornar um valor. |
bool, bvec2, bvec3, bvec4 (bool2, bool3, bool4) . |
Escalar/vetor booleano |
int, ivec2, ivec3, ivec4 (int2, int3, int4) |
highp inteiro/vetor com sinal
|
float, vec2, vec3, vec4 (float2, float3, float4)
|
highp (precisão única) de ponto flutuante
escalar/vetor |
short, short2, short3, short4
|
equivalente a mediump int número inteiro/vetor com sinal |
half, half2, half3, half4 |
equivalente a mediump float escalar/vetor |
mat2, mat3, mat4 (float2x2, float3x3, float4x4) |
Matriz float 2x2, 3x3, 4x4
|
half2x2, half3x3, half4x4 |
Equivalente aos tipos de matriz mediump float |
Mínimo de precisão e intervalo
Eles são a precisão e o intervalo mínimos garantidos associados a cada
modificador com base na especificação do OpenGL ES 2.0. Como a maioria dos dispositivos
oferece suporte ao ES 3.0, eles têm precisão/intervalo highp
e
intervalo int mediump
mais garantidos. 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 é necessariamente menor que mediump
, e mediump
não é necessariamente menor que highp
. Atualmente, a AGSL converte lowp
para mediump
na saída final.
Modificador | Intervalo "flutuante" | Intervalo de magnitude "float" | Precisão de "float" | Intervalo "int" |
---|---|---|---|---|
alto | \(\left\{-2^{62},2^{62}\right\}\) | \(\left\{2^{-62},2^{62}\right\}\) | Parente: \(2^{-16}\) | \(\left\{-2^{16},2^{16}\right\}\) |
Médio | \(\left\{-2^{14},2^{14}\right\}\) | \(\left\{2^{-14},2^{14}\right\}\) | Parente: \(2^{-10}\) | \(\left\{-2^{10},2^{10}\right\}\) |
baixa | \(\left\{-2,2\right\}\) | \(\left\{2^{-8},2\right\}\) | Absoluto: \(2^{-8}\) | \(\left\{-2^{8},2^{8}\right\}\) |
Além da sintaxe de subscrito da 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 para acessar vetores que representam cores.
vect.LTRB
: use quando o vetor representa um retângulo (não em GLSL).
Na AGSL, 0 e 1 podem ser usados para produzir um 0 ou 1 constante nesse canal.
Por exemplo: vect.rgb1 == vec4(vect.rgb,1)
Estruturas e matrizes
As estruturas são declaradas com a mesma sintaxe da GLSL, mas a AGSL só oferece suporte a estruturas em escopo global.
struct type-name {
members
} struct-name; // optional variable declaration.
Apenas matrizes unidimensionais são compatíveis com um tamanho de matriz explícito, usando a sintaxe de estilo C ou GLSL:
Nome da variável <tipo de base>[<tamanho da matriz>], por exemplo: half[10] x;
<base type> nome da variável[<array size>], por exemplo: half x[10];
As matrizes não podem ser retornadas de uma função, copiadas, atribuídas ou comparadas. As restrições de matriz 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 no primitivo
que está sendo processado.
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 que são transmitidos 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 entre chaves explícitos. A declaração de y
no
exemplo a seguir não é permitida:
if (condition)
int y = 0;
Princípios básicos de matriz/estrutura/matriz
Exemplos de construtor de matriz
Quando uma matriz é construída com um único valor, todos os valores na diagonal recebem esse valor, enquanto o restante recebe zeros. Portanto, float2x2(1.0)
criaria uma matriz de identidade 2x2.
Quando uma matriz é construída com vários valores, as colunas são preenchidas primeiro (ordem maior da coluna).
Observe que, ao contrário da GLSL, construtores que reduzem o número de componentes de um
vetor transmitido não têm suporte, mas é possível usar o swizzling para ter o mesmo
efeito. Para construir um vec3
com base em um vec4
na AGSL com o mesmo comportamento que a
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 sintaxe de assinatura 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 os campos de estrutura usando o operador de ponto .
. 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 da matriz [ ]
. Por exemplo:
diffuseColor += lightIntensity[3] * NdotL;
Operadores
Numerados em ordem de precedência. Os operadores relacionais e de igualdade > < <= >= == != são avaliados como um booleano. Para comparar vetores em componentes, 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 de subscrito, incremento e diminuição pós-fixo do swizzle | Da esquerda para a direita |
3 | ++ -- + - !
|
incremento e diminuição de prefixo unário | Da direita para a esquerda |
4 | * / |
multiplicar e dividir | Da esquerda para a direita |
5 | + - |
adicionar e subtrair | Da esquerda para a direita |
7 | < > <= >= |
relacional | Da esquerda para a direita |
8 | == != |
igualdade/desigualdade | Da esquerda para a direita |
12 | && |
AND lógico | 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 aritmética atribuição aritmética atribuição | Da esquerda para a direita |
17 | , |
sequence | Da esquerda para a direita |
Operações de matriz e vetorial
Quando aplicados a valores escalares, os operadores aritméticos resultam em um escalar. Para operadores diferentes do módulo, se um operando for escalar e o outro for um vetor ou matriz, a operação será realizada por componentes e resultará no mesmo tipo de vetor ou matriz. Se as duas operações forem vetores do mesmo tamanho, a operação será realizada por componentes (e retornará o mesmo tipo de vetor).
Operação | Descrição |
---|---|
m = f * m |
Multiplicação de matrizes por um valor escalar |
v = f * v |
Multiplicação de vetores por componentes por um valor escalar |
v = v * v |
Multiplicação de vetores por componente por um valor vetorial |
m = m + m |
Adição por componente de matriz |
m = m - m |
Subtração por componente da 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 nossa matriz, o operador de multiplicação poderá ser usado para fazer a multiplicação algébrica de linhas e colunas.
Operação | Descrição |
---|---|
m = v * m |
Multiplicação algébrica linear de matriz de vetor de linha * |
m = m * v |
Multiplicação algébrica linear de vetor de coluna de matriz * |
Use as funções integradas para produto escalar vetorial, produto cruzado e multiplicação por componentes:
Função | Descrição |
---|---|
f = dot(v, v) |
Produto escalar vetorial |
v = cross(v, v) |
Vetor de vários produtos |
m = matrixCompMult(m, m) |
Multiplicação por componente |
Controle do programa
Chamada de função | Chamada por valor-retorno |
---|---|
Iteração | for (<init>;<test>;<next>) { break, continue } |
Seleção | if ( ) { } if ( ) { } else { } switch () { break, case }
- último caso padrão |
Pular | break, continue, return (descartar não é permitido) |
Entrada | half4 main(float2 fragCoord) |
Limitações de loop for
Assim como na GLSL ES 1.0, as repetições "for" são bastante limitadas. O compilador precisa ser capaz
de desencadear 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 calculado durante a
compilação. A instrução next
é ainda mais 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 em relação a componentes, ou seja, a função é aplicada por componente. Observamos quando esse não é o caso.
Funções de ângulo e trigonométricas
Os parâmetros de função especificados como um ângulo são considerados em unidades de radianos. Em nenhum caso nenhuma dessas funções resultará 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) |
Seno 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 cujo arco trigonométrico é $ \left[{y\over x}\right] $ no intervalo de $ \left[-\pi,\pi\right] $ |
GT atan(GT y_over_x)
|
Retorna um ângulo cujo arco trigonométrico
é 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 do módulo x de y |
GT mod(GT x, float y) |
Retorna o valor do módulo x de 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 fixado entre minVal e maxVal. |
GT clamp(GT x, float
minVal, float maxVal) |
Retorna x fixado entre minVal e maxVal |
GT saturate(GT x) |
Retorna x fixado entre 0,0 e 1,0 |
GT mix(GT x, GT y
GT a) |
Retorna a combinação linear de x e y |
GT mix(GT x, GT y,
float a) |
Retorna a combinação 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) |
Executa a interpolação Hermite entre 0 e 1 quando borda0 < x < borda1 |
GT smoothstep(float
edge0, float edge1,
GT x) |
Executa a interpolação Hermite entre 0 e 1 quando borda0 < x < borda1 |
Funções geométricas
Essas funções operam em vetores como vetores, não em componentes. GT são vetores flutuantes/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 os pontos |
float/half dot(GT x,
GT y) |
Retorna um produto escalar |
float3/half3
cross(float3/half3 x,
float3/half3 y) |
Retorna vários produtos |
GT normalize(GT x) |
Normalizar o vetor para o comprimento 1 |
GT faceforward(GT N,
GT I, GT Nref) |
Retorna N se ponto(Nref, I) < 0, caso contrário, -N. |
GT reflect(GT I, GT N) |
Direção do reflexo I - 2 * ponto(N,I) * N. |
GT refract(GT I, GT N,
float/half eta) |
Retorna o vetor de refração |
Funções de matriz
O tapete é qualquer tipo de matriz quadrada.
Função | Descrição |
---|---|
mat matrixCompMult(mat
x, mat y) |
Multiplicar x por y por componente |
mat inverse(mat m) |
Retorna a inversa de m |
Funções relacionais de vetores
Comparar x e y por componente. Os tamanhos dos vetores de entrada e retorno para uma chamada específica precisam ser correspondentes. T é a união dos tipos de vetor de número inteiro e ponto flutuante. 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 algum 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 de cor para Alfa não pré-multiplicado |
half3 toLinearSrgb(half3
color) |
Transformação do espaço de cores para SRGB linear |
half3 fromLinearSrgb(half3
color) |
Transformação do espaço de cores |
Amostragem do sombreador (avaliação)
Os tipos de Sampler não são compatíveis, mas é possível avaliar outros sombreadores. Se você precisa testar uma textura, é possível criar um objeto BitmapShader e adicioná-lo como um uniforme. Você pode fazer isso 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 enorme flexibilidade, mas sombreadores complexos podem ser caros de avaliar, especialmente em um loop.
uniform shader image;
image.eval(coord).a // The alpha channel from the evaluated image shader
Amostragem bruta de buffer
Embora a maioria das imagens contenha cores que precisam ser gerenciadas por cores, algumas contêm dados que não são cores, incluindo imagens que armazenam normais, propriedades do material (por exemplo, aspereza), heightmaps ou qualquer outro dados puramente matemáticos que sejam armazenados 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.