Unterschiede zwischen AGSL und GLSL

Die Syntax von AGSL und GLSL ist sehr ähnlich, sodass viele GLSL-Fragment-Shader Effekte, die mit minimalen Änderungen auf Android übertragen werden können. AGSL korrigiert seine GLSL mit GLSL ES 1.0, der von OpenGL ES 2.0 verwendeten Schattierungssprache, für maximale Gerätereichweite.

Ein GLSL-Fragment-Shader steuert das gesamte Verhalten der GPU zwischen den und die Blending-Hardware. Dieser Shader erledigt die gesamte Arbeit für die Berechnung Farbe. Die dadurch erzeugte Farbe wird genau in die Mischphase eingespeist. der Pipeline. Wenn Sie einen Shader in AGSL schreiben, programmieren Sie eine der Android-Grafikpipeline. Viele der sprachlichen Unterschiede gehen darauf zurück.

Shader-Ausführung

Genau wie bei einem GLSL-Shader beginnt ein AGSL-Shader mit der Ausführung in einer Hauptfunktion. Anders als bei GLSL wird für diese Funktion die Shader-Position in „local“ Koordinaten als . Dies ähnelt gl_FragCoord, jedoch nicht als Framebuffer. Koordinaten wurden möglicherweise übersetzt, bevor Ihr Shader. Der Shader gibt dann die Pixelfarbe als vec4 im Format „Medium“ oder hohe Genauigkeit (ähnlich out vec4 color oder gl_FragColor in GLSL).

mediump vec4 main(in vec2 fragCoord)

Koordinatenraum

GLSL- und AGSL-Koordinatenräume

Schattierung mit GLSL im Vergleich zu nahezu identischer Shader mit AGSL gezeichnet

AGSL und GLSL verwenden standardmäßig unterschiedliche Koordinaten. In GLSL ist das Fragment -Koordinate (fragCoord) ist relativ zu links unten. AGSL entspricht dem Bildschirm Koordinatensystem von Canvas, Das bedeutet, dass die Y-Achse in der oberen linken Ecke beginnt. Bei Bedarf können Sie kann zwischen diesen beiden Leerzeichen konvertiert werden, indem er die Auflösung als Einheitlichkeit übergibt und resolution.y - fragCoord.y als Wert auf der Y-Achse verwenden. Alternativ können Sie können Sie eine lokale Transformationsmatrix auf Ihren Shader anwenden.

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

Genauigkeit und Typen

GLSL-kompatible Präzisionsmodifikatoren werden unterstützt, AGSL führt jedoch half- und short-Typen, die auch eine mittlere Genauigkeit darstellen.

Vektortypen können als <Basistyp><Spalten> deklariert werden. Sie können float2 statt vec2 und bool4 statt bvec4. Matrixtypen können als <Basistyp><Spalten>x<Zeilen> deklariert werden, sodass float3x3 statt mat3. AGSL ermöglicht auch Deklarationen im GLSL-Stil für mat und vec. Diese Typen werden ihrer Gleitkommazahl zugeordnet. Äquivalente.

Präprozessor

AGSL unterstützt den GLSL-Stil nicht Präprozessor Anweisungen. Wandeln Sie #define-Anweisungen in const-Variablen um. Compiler von AGSL unterstützt die konstante Faltung und die Eliminierung von Zweigen für const-Variablen, sodass diese effizient zu sein.

Farbräume

Android-Apps werden für Farben verwaltet. Der Farbraum eines Canvas bestimmt, den Farbraum für das Zeichnen. Quellcontent (z. B. Shader, einschließlich BitmapShader) auch Farbräume haben.

Für bestimmte Effekte, z. B. für eine physikalische Belichtung, ist eine Berechnung durch in einem linearen Farbraum an. Um dies zu unterstützen, bietet AGSL diese Funktionen:

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

Sie wandeln Farben zwischen dem Arbeitsfarbraum und dem LINEAR_EXTENDED_SRGB Farbraum. Dieser Bereich verwendet die sRGB-Grundfarben (Gamut) und eine lineare Übertragungsfunktion. Sie stellt Werte außerhalb der sRGB-Gamut mit erweiterten (unter 0,0 und über 1,0) liegen.

Uniformen

Da AGSL nicht weiß, ob Uniformen Farben enthalten, werden sie nicht automatisch angewendet Farbkonvertierung hinzu. Sie können half4/float4/vec4 mit folgendem Label versehen: layout(color), wodurch Android informiert wird, dass das Trikot als und ermöglicht es Android, den einheitlichen Wert in die Arbeitsfarbe Leerzeichen.

Deklariere die Uniform in AGSL wie folgt:

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

Im Android-Code können Sie die Einheit dann so festlegen:

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