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
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())