AGSL jest w dużej mierze zgodny z GLSL ES 1.0. Więcej informacji znajdziesz w odpowiedniej funkcji w dokumentacji języka opisu obrazu OpenGL ES. W miarę możliwości staramy się w tej dokumentacji wskazywać różnice między AGSL a GLSL.
Typy
AGSL obsługuje typy GLSL ES 1.0 oraz dodatkowy sposób reprezentacji typów wektorów i macierzy. AGSL obsługuje dodatkowe typy short
i half
, aby reprezentować średnią precyzję.
Typy podstawowe
Typ | Opis |
---|---|
void
|
Brak wartości zwracanej przez funkcję lub pusta lista parametrów. W przeciwieństwie do GLSL, funkcje bez typu zwracania void muszą zwracać wartość. |
bool, bvec2, bvec3, bvec4 (bool2, bool3, bool4) . |
Wartość logiczna skalarna/wektory |
int, ivec2, ivec3, ivec4 (int2, int3, int4) |
highp podpisana liczba całkowita/wektory
|
float, vec2, vec3, vec4 (float2, float3, float4)
|
highp (pojedyncza precyzja) zmiennoprzecinkowa wektorowa/skalarna |
short, short2, short3, short4
|
odpowiada mediump int podpisanemu całkowitemu/wektorowi |
half, half2, half3, half4 |
jest tożsame co mediump float skalar/wektor |
mat2, mat3, mat4 (float2x2, float3x3, float4x4) |
Matryca 2 x 2, 3 x 3 lub 4 x 4 float
|
half2x2, half3x3, half4x4 |
Odpowiednik typów macierzy mediump float |
Minimalna dokładność i zakres
Są to minimalna gwarantowana dokładność i zakres powiązane z każdym modyfikatorem zgodnie ze specyfikacją OpenGL ES 2.0. Większość urządzeń obsługuje ES 3.0, więc mają one większą gwarantowaną dokładność i zakres highp
oraz zakres int mediump
. Modyfikatory dokładności można stosować do parametrów i zmiennych skalarnych, wektorowych oraz macierzy. Gwarantowane są tylko minimalne wartości wymienione poniżej. lowp
nie musi mieć niższej dokładności niż mediump
, a mediump
nie musi mieć niższej dokładności niż highp
. Obecnie AGSL konwertuje lowp
na mediump
w końcowym wyjściu.
Modyfikator | Zakres „float” | Zakres wielkości „float” | Dokładność „float” | Zakres „int” |
---|---|---|---|---|
highp | \(\left\{-2^{62},2^{62}\right\}\) | \(\left\{2^{-62},2^{62}\right\}\) | Względne: \(2^{-16}\) | \(\left\{-2^{16},2^{16}\right\}\) |
mediump | \(\left\{-2^{14},2^{14}\right\}\) | \(\left\{2^{-14},2^{14}\right\}\) | Względne: \(2^{-10}\) | \(\left\{-2^{10},2^{10}\right\}\) |
lowp | \(\left\{-2,2\right\}\) | \(\left\{2^{-8},2\right\}\) | Bezwzględne: \(2^{-8}\) | \(\left\{-2^{8},2^{8}\right\}\) |
Oprócz składni indeksu numerycznego tablicy, np. 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
– używaj, gdy odczytuje się wektory, które reprezentują punkty lub normalne.
vect.rgba
– używaj, gdy uzyskujesz dostęp do wektorów, które reprezentują kolory.
vect.LTRB
– używaj, gdy wektor reprezentuje prostokąt (nie w GLSL).
W AGSL wartości 0 i 1 mogą być używane do generowania stałych wartości 0 lub 1 na danym kanale.
Przykład: vect.rgb1 == vec4(vect.rgb,1)
Struktury i tablice
Struktury są deklarowane za pomocą tej samej składni co w GLSL, ale AGSL obsługuje tylko struktury o zakresie globalnym.
struct type-name {
members
} struct-name; // optional variable declaration.
Obsługiwane są tylko tablice jednowymiarowe z wyraźnym rozmiarem, zdefiniowanym za pomocą składni C lub GLSL:
<base type>[<array size>] nazwa zmiennej – np. half[10] x;
<base type> nazwa zmiennej[<rozmiar tablicy>] – np. half x[10];
Tablic nie można zwracać z funkcji, kopiować, przypisywać ani porównywać. Ograniczenia tablic są rozpowszechniane na struktury zawierające tablice. Indeksowanie tablic jest możliwe tylko za pomocą stałej lub zmiennej pętli.
Eliminacje
Typ | Opis |
---|---|
const
|
Stałe wartościowe w czasie kompilacji lub parametry funkcji tylko do odczytu. |
uniform
|
Wartość nie zmienia się w przypadku przetwarzanego typu pierwotnego.
Uniformy są przekazywane z Androida za pomocą metod RuntimeShader dla setColorUniform , setFloatUniform , setIntUniform , setInputBuffer i setInputShader . |
in
|
Parametry funkcji przekazywane do funkcji. To jest ustawienie domyślne. |
out
|
Parametry funkcji z wynikiem. Musi mieć taką samą dokładność jak definicja funkcji. |
inout
|
Parametry, które są przekazywane do funkcji i z niej. Musi być używana z tą samą dokładnością co definicja funkcji. |
Deklaracja zmiennej
Deklaracje muszą być w wyraźnym zakresie nawiasów. Deklaracja y
w tym przykładzie jest niedozwolona:
if (condition)
int y = 0;
Podstawy dotyczące macierzy, struktur i tablic
Przykłady konstruktora macierzy
Gdy macierz jest tworzona z jedną wartością, wszystkie wartości na przekątnej mają tę wartość, a pozostałe są równe 0. float2x2(1.0)
utworzy więc macierz tożsamości 2 x 2.
Gdy tworzona jest matryca z wieloma wartościami, najpierw wypełniane są kolumny (kolejność kolumn).
Pamiętaj, że w odróżnieniu od GLSL konstruktory, które zmniejszają liczbę komponentów przekazywanego wektora, nie są obsługiwane, ale możesz użyć swizlowania, aby uzyskać ten sam efekt. Aby utworzyć vec3
z vec4
w AGSL z tym samym działaniem jak w GLSL, określ vec3 nv = quadVec.xyz
.
Przykład konstruktora struktury
struct light { float intensity; float3 pos; };
// literal integer constants auto-converted to floating point
light lightVar = light(3, float3(1, 2, 3.0));
Elementy macierzy
Dostęp do elementów macierzy za pomocą składnika tablicowego.
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
Pola struktury
Wybierz pola struktury za pomocą operatora kropka .
. Operatory:
Operator | Opis |
---|---|
. |
selektor pól |
==, != |
równość |
= |
projekt |
Elementy tablicy
Do elementów tablicy uzyskuje się dostęp za pomocą operatora indeksowania tablicy [ ]
. Przykład:
diffuseColor += lightIntensity[3] * NdotL;
Operatorzy
Numerowane według kolejności ważności. Operatory relacji i równości > < <= >= == != zwracają wartość logiczną. Aby porównać wektory poszczególnymi składowymi, użyj funkcji takich jak lessThan()
, equal()
itp.
Operator | Opis | Związek | |
---|---|---|---|
1 | () |
grupowanie w nawiasach | Nie dotyczy |
2 | [] () . ++ --
|
indeks tablicy, wywołanie funkcji i struktura konstruktora, selektor pola lub metody, zamiana, postfiks zwiększania i zmniejszania | Od lewej do prawej |
3 | ++ -- + - !
|
prefiks zwiększania i zmniejszania unary | Od prawej do lewej |
4 | * / |
mnożenie i dzielenie | Od lewej do prawej |
5 | + - |
dodawanie i odejmowanie, | Od lewej do prawej |
7 | < > <= >= |
relacyjny | Od lewej do prawej |
8 | == != |
równość/nierówność | Od lewej do prawej |
12 | && |
operator logiczny AND | Od lewej do prawej |
13 | ^^ |
operator logiczny XOR | Od lewej do prawej |
14 | || |
operator logiczny LUB | Od lewej do prawej |
15 | ?\:
|
selection (jeden cały operand) | Od lewej do prawej |
16 | = += -= *= /=
|
assignment arithmetic assignment arithmetic assignment | Od lewej do prawej |
17 | , |
sequence | Od lewej do prawej |
Operacje na macierzach i wektorach
Po zastosowaniu do wartości skalarnych operatory arytmetyczne dają wynik skalarny. W przypadku operatorów innych niż modulo, jeśli jeden operand jest skalarem, a drugi wektorem lub macierzą, operacja jest wykonywana komponentowo i daje ten sam typ wektora lub macierzy. Jeśli obie operacje są wektorami o tym samym rozmiarze, operacja jest wykonywana komponentowo (i zwraca ten sam typ wektora).
Operacja | Opis |
---|---|
m = f * m |
Mnożenie macierzy element po elemencie przez wartość skalarną |
v = f * v |
Mnożenie wektora element po elemencie przez wartość skalarną |
v = v * v |
Pomnażanie wektora element po elemencie przez wartość wektorową |
m = m + m |
Dodawanie elementów macierzy |
m = m - m |
Odejmowanie elementów macierzy |
m = m * m |
Prosta mnożnia algebraiczna |
Jeśli jeden operand jest wektorem pasującym do rozmiaru wiersza lub kolumny naszej macierzy, operator mnożenia może służyć do algebraicznego mnożenia wierszy i kolumn.
Operacja | Opis |
---|---|
m = v * m |
Wektor wiersza * macierz liniowa algebraiczna mnożenie |
m = m * v |
Macierz * wektor kolumnowy – mnożenie liniowo-algebraiczne |
Użyj wbudowanych funkcji do iloczynu skalarnego, iloczynu wektorowego i iloczynu komponentowego:
Funkcja | Opis |
---|---|
f = dot(v, v) |
Iloczyn skalarny wektorów |
v = cross(v, v) |
Iloczyn wektorowy |
m = matrixCompMult(m, m) |
Mnożenie komponentów |
Kontrola programu
Wywołanie funkcji | Wywołanie funkcji z wartością zwracaną |
---|---|
Iteracja | for (<init>;<test>;<next>) { break, continue } |
Zaznaczenie | if ( ) { } if ( ) { } else { } switch () { break, case } - domyślnie ostatnia litera |
Przejdź | break, continue, return (odrzucenie nie jest dozwolone) |
Wpis | half4 main(float2 fragCoord) |
Ograniczenia pętli for
Podobnie jak w GLSL ES 1.0, pętle „for” są dość ograniczone; kompilator musi mieć możliwość rozwinięcia pętli. Oznacza to, że inicjalizator, warunek testu i instrukcja next
muszą używać stałych, aby wszystko można było obliczyć w czasie kompilacji. Oświadczenie next
jest dodatkowo ograniczone do użycia ++, --, +=, or -=
.
Wbudowane funkcje
GT
(typ ogólny) to float
, float2
, float3
, float4
lub half
, half2
, half3
, half4
.
Większość z nich działa na poziomie komponentu (funkcja jest stosowana osobno do każdego komponentu). W przeciwnym razie jest to zaznaczone.
Kąty i funkcje trygonometryczne
Parametry funkcji podane jako kąt są uznawane za kąt w radianach. Żadna z tych funkcji nie spowoduje błędu dzielenia przez 0. Jeśli dzielnik proporcji ma wartość 0, wyniki nie będą określone.
Funkcja | Opis |
---|---|
GT radians(GT degrees) |
konwertuje stopnie na radiany, |
GT degrees(GT radians) |
Przekształca radiany na stopnie |
GT sin(GT angle) |
Standardowy sinus |
GT cos(GT angle) |
Standardowy cosinus |
GT tan(GT angle) |
Standardowa wartość dotykowa |
GT asin(GT x)
|
Zwraca kąt, którego sinus jest równy x w zakresie $ \left[-{\pi\over 2},{\pi\over 2}\right] $ |
GT acos(GT x)
|
Zwraca kąt, którego cosinus jest równy x, w zakresie $ \left[0,\pi\right] $. |
GT atan(GT y, GT x)
|
Zwraca kąt, którego trójkątny arcus tangens jest równy $ \left[{y\over x}\right] $ w zakresie $ \left[-\pi,\pi\right] $ |
GT atan(GT y_over_x)
|
Zwraca kąt, którego arctangens trygonometryczny jest równy y_over_x w zakresie $ \left[-{\pi\over 2},{\pi\over 2}\right] $ |
Funkcje wykładnicze
Funkcja | Opis |
---|---|
GT pow(GT x, GT y) |
Zwraca $ x^y $ |
GT exp(GT x) |
zwraca $ e^x $ |
GT log(GT x) |
Zwraca $ ln(x) $ |
GT exp2(GT x) |
Zwraca wartość 2^x $ |
GT log2(GT x) |
zwraca wartość $ log_2(x) $ |
GT sqrt(GT x) |
Zwraca $ \sqrt{x} $ |
GT inversesqrt(GT x) |
Zwraca wartość $ 1\over{\sqrt{x}} $ |
Funkcje wspólne
Funkcja | Opis |
---|---|
GT abs(GT x) |
Wartość bezwzględna |
GT sign(GT x) |
Zwraca -1.0, 0.0 lub 1.0 w zależności od znaku x. |
GT floor(GT x) |
Najbliższa liczba całkowita < x |
GT ceil(GT x) |
Najbliższa liczba całkowita > x |
GT fract(GT x) |
Zwraca część ułamkową liczby x. |
GT mod(GT x, GT y) |
Zwraca wartość x modulo y. |
GT mod(GT x, float y) |
Zwraca wartość x modulo y. |
GT min(GT x, GT y) |
Zwraca minimalną wartość x lub y |
GT min(GT x, float y) |
Zwraca minimalną wartość x lub y |
GT max(GT x, GT y) |
Zwraca maksymalną wartość x lub y |
GT max(GT x, float y) |
Zwraca maksymalną wartość x lub y |
GT clamp(GT x, GT
minVal, GT maxVal) |
Zwraca wartość x ograniczoną do zakresu od minVal do maxVal. |
GT clamp(GT x, float
minVal, float maxVal) |
Zwraca wartość x ściśnioną między minVal i maxVal |
GT saturate(GT x) |
Zwraca wartość x ściśniętą w zakresie od 0,0 do 1,0 |
GT mix(GT x, GT y,
GT a) |
Zwraca mieszankę liniową x i y. |
GT mix(GT x, GT y,
float a) |
Zwraca mieszankę liniową x i y. |
GT step(GT edge, GT x) |
Zwraca 0,0, jeśli x < edge, w przeciwnym razie zwraca 1,0. |
GT step(float edge,
GT x) |
Zwraca 0,0, jeśli x < edge, w przeciwnym razie 1,0. |
GT smoothstep(GT edge0,
GT edge1, GT x) |
Przeprowadza interpolację Hermite'a w zakresie od 0 do 1, gdy edge0 < x < edge1 |
GT smoothstep(float
edge0, float edge1,
GT x) |
Przeprowadza interpolację Hermite'a w zakresie od 0 do 1, gdy edge0 < x < edge1 |
Funkcje geometryczne
Te funkcje działają na wektorach jako wektory, a nie na ich komponentach. GT to wektory typu float/half o rozmiarach 2–4.
Funkcja | Opis |
---|---|
float/half length
(GT x) |
Zwraca długość wektora. |
float/half distance(GT
p0, GT p1) |
Zwraca odległość między punktami. |
float/half dot(GT x,
GT y) |
Zwraca iloczyn skalarny |
float3/half3
cross(float3/half3 x,
float3/half3 y) |
Zwraca iloczyn wektorowy |
GT normalize(GT x) |
Normalizacja wektora do długości 1 |
GT faceforward(GT N,
GT I, GT Nref) |
Zwraca N, jeśli dot(Nref, I) < 0, w przeciwnym razie zwraca –N. |
GT reflect(GT I, GT N) |
Kierunek odbicia I = 2 * dot(N,I) * N. |
GT refract(GT I, GT N,
float/half eta) |
Zwraca wektor załamania promieniowania. |
Funkcje macierzy
Typ mat to dowolny kwadratowy typ macierzy.
Funkcja | Opis |
---|---|
mat matrixCompMult(mat
x, mat y) |
Pomnóż x przez y według komponentów |
mat inverse(mat m) |
Zwraca odwrotność m. |
Funkcje wektorowe
Porównaj komponenty x i y. Rozmiary wektora wejściowego i zwrotnego w przypadku danego wywołania muszą być takie same. T jest iloczykiem wektorów typu liczba całkowita i liczba zmiennoprzecinkowa. BV to wektor logiczny o rozmiarze odpowiadającym wektorom wejściowym.
Funkcja | Opis |
---|---|
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 , jeśli dowolny składnik x jest true |
bool all(BV x) |
true , jeśli wszystkie składniki x są true . |
BV not(BV x) |
uzupełnienie logiczne x |
Funkcje kolorów
Funkcja | Opis |
---|---|
vec4 unpremul(vec4
color) |
Konwertuje wartość koloru na nieskalibrowaną wartość alfa. |
half3 toLinearSrgb(half3
color) |
Przekształcenie przestrzeni kolorów na liniową sRGB |
half3 fromLinearSrgb(half3
color) |
Przekształcanie przestrzeni kolorów |
Próbkowanie shaderów (ocena)
Typy próbkowania nie są obsługiwane, ale możesz oceniać inne shadery. Jeśli chcesz pobrać próbkę tekstury, możesz utworzyć obiekt BitmapShader i dodać go jako uniform. Możesz to zrobić w przypadku dowolnego shadera, co oznacza, że możesz bezpośrednio ocenić dowolny shader Androida bez wcześniejszego przekształcania go w Bitmap, w tym inne obiekty RuntimeShader. Daje to ogromną elastyczność, ale złożone shadery mogą być kosztowne w przetwarzaniu, zwłaszcza w pętli.
uniform shader image;
image.eval(coord).a // The alpha channel from the evaluated image shader
Próbkowanie bufora surowego
Chociaż większość obrazów zawiera kolory, które powinny być poddane zarządzaniu kolorami, niektóre obrazy zawierają dane, które nie są kolorami, w tym obrazy przechowujące normalne, właściwości materiału (np. chropowatość), mapy wysokości lub inne dane czysto matematyczne, które są przechowywane w obrazie. Gdy używasz tego typu obrazów w AGSL, możesz użyć BitmapShader jako ogólnego bufora nieprzetworzonego, używając RuntimeShader#setInputBuffer. Dzięki temu unikniesz przekształcania i filtrowania przestrzeni barw.