Różnice między AGSL a GLSL

Składnia AGSL i GLSL jest bardzo podobna, co umożliwia korzystanie z wielu funkcji cieniowania fragmentów GLSL które można przenieść na Androida przy minimalnych zmianach. AGSL poprawia swój GLSL z ustawioną funkcją GLSL ES 1.0 (język cieniowania używany przez OpenGL ES 2.0), aby aby zmaksymalizować zasięg urządzenia.

Moduł cieniowania fragmentów GLSL steruje całym działaniem GPU między do rastrowania i mieszania. Wykonuje on całą pracę, aby obliczyć a generowany przez niego kolor jest taki, jaki jest dostarczany na etap mieszania w całym potoku. Pisząc program do cieniowania w języku migowym, programujesz etap w postaci interfejsu graficznego Androida. Wiele z nich wynika z różnic językowych.

Wykonanie shadera

Podobnie jak w przypadku cieniowania GLSL, cieniowanie AGSL rozpoczyna wykonywanie głównej funkcji. W przeciwieństwie do GLSL funkcja przyjmuje pozycję cieniowania „local” jako współrzędnych . Wygląda to podobnie do gl_FragCoord, ale nie do bufora ramki współrzędne mogą zostać przetłumaczone przed wywołaniem danego numeru program do cieniowania. Następnie cieniowanie zwraca kolor piksela jako vec4 w średnim lub duża precyzja (podobna do wartości out vec4 color lub gl_FragColor w GLSL).

mediump vec4 main(in vec2 fragCoord)

Obszar współrzędnych

Odstępy GLSL i AGSL

Shader narysowany przy użyciu GLSL lub Prawie identyczne cieniowanie utworzone za pomocą języka AGSL

Domyślnie AGSL i GLSL korzystają z różnych odstępów współrzędnych. W GLSL fragment współrzędna (fragCoord) jest ustawiona względem lewego dolnego rogu. AGSL pasuje do ekranu układ współrzędnych Canvas, co oznacza, że oś Y zaczyna się od lewego górnego rogu. W razie potrzeby można zamienić te dwie przestrzenie, przekazując rozdzielczość jako jednolitą rozdzielczość i za pomocą resolution.y - fragCoord.y jako wartości na osi Y. Ewentualnie może zastosować lokalną macierz przekształceń do cieniowania.

// AGSL to GLSL coordinate space transformation matrix
val localMatrix = Matrix()
localMatrix.postScale(1.0f, -1.0f)
localMatrix.postTranslate(0.0f, viewHeight)
gridShader.setLocalMatrix(localMatrix)

Precyzja i typy

Obsługiwane są modyfikatory precyzji zgodne z GLSL, ale AGSL wprowadza Typy half i short, które również reprezentują średnią precyzję.

Typy wektorów można deklarować jako <typ_podstawowy>kolumny>. Za pomocą float2 zamiast vec2 i bool4 zamiast bvec4. Typy macierzy można zadeklarować jako <typ bazowy><kolumny>x<wiersze>, więc float3x3 zamiast mat3. AGSL dopuszcza też deklaracje w stylu GLSL dla mat i vec, które są zmapowane na liczbę zmiennoprzecinkową ich odpowiedniki.

Procesor wstępny

AGSL nie obsługuje stylu GLSL podmiot przetwarzający dane dyrektywy. Przekonwertuj instrukcje #define na zmienne stałe. Kompilator AGSL obsługuje stałe zawijanie i eliminację gałęzi dla zmiennych stałych, dzięki czemu te wartości będzie skuteczne.

przestrzenie kolorów,

Aplikacje na Androida zarządzają kolorami. Przestrzeń kolorów Canvas określa roboczej przestrzeni kolorów do rysowania. Treści źródłowe (takie jak programy do cieniowania, BitmapShader) mają też przestrzenie kolorów.

W przypadku niektórych efektów, takich jak fizycznie precyzyjne oświetlenie, obliczenia należy w liniowej przestrzeni kolorów. Aby ułatwić sobie zadanie, AGSL zapewnia funkcje:

half3 toLinearSrgb(half3 color)
half3 fromLinearSrgb(half3 color)

Zamieniają one barwę między barwną a przestrzenią kolorów Androida LINEAR_EXTENDED_SRGB przestrzeni kolorów. W przestrzeni tej używane są kolory podstawowe sRGB (gamut), transferu danych. Reprezentuje wartości spoza zakresu sRGB za pomocą rozszerzonej wartości zakresu (poniżej 0,0 i powyżej 1,0).

Stroje

AGSL nie wie, czy uniformy zawierają kolory, więc nie zostaną zastosowane automatycznie konwersję koloru. Możesz oznaczyć etykietą half4/float4/vec4 tą etykietą layout(color), w której Android wie, że mundur będzie używany jako koloru, dzięki czemu Android przekształca jednolitą wartość na kolor roboczy. kosmosu.

W AGSL zadeklaruj mundur w ten sposób:

layout(color) uniform half4 iColor;  // Input color
uniform float2 iResolution;          // Viewport resolution (pixels)

W kodzie Androida możesz następnie ustawić uniform w ten sposób:

shader.setColorUniform("iColor", Color.GREEN)
shader.setFloatUniform("iResolution", canvas.width.toFloat(), canvas.height.toFloat())