Darüber hinaus haben wir eine vordefinierte gl_FragColor.
Beginnen wir damit. Nein, Sie haben das nicht vordefiniert gl_FragColor
. Das wurde aus OpenGL 3.1 und höher entfernt. Es sei denn, Sie verwenden Kompatibilität (in diesem Fall sollten Ihre 3.30-Shader sagen#version 330 compatibility
oben stehen), sollten Sie diese niemals verwenden.
Zurück zu den benutzerdefinierten Fragment-Shader-Ausgaben. Aber zuerst eine kurze Analogie.
Erinnern Sie sich, wie Sie in Vertex-Shadern Eingaben haben? Und diese Eingänge repräsentieren Vertexattribut - Indizes, die Zahlen , die Sie passieren zu glVertexAttribPointer
und glEnableVertexAttribArray
und so weiter? Sie legen fest, welche Eingabe von welchem Attribut abgerufen wird. In GLSL 3.30 verwenden Sie diese Syntax:
layout(location = 2) in color;
Dadurch wird festgelegt, dass die color
Vertex-Shader-Eingabe von Attributposition 2 stammt. Vor 3.30 (oder ohne ARB_explicit_attrib_location) müssten Sie dies entweder explizit mit einrichten, glBindAttrbLocation
bevor Sie das Programm verknüpfen, oder das Programm nach dem Attributindex abfragen glGetAttribLocation
. Wenn Sie keinen expliziten Attributspeicherort angeben, weist GLSL einen Speicherort willkürlich zu (dh auf implementierungsdefinierte Weise).
Das Einstellen im Shader ist fast immer die bessere Option.
In jedem Fall funktionieren Fragment-Shader-Ausgaben fast genauso. Fragment-Shader können in mehrere Ausgabefarben schreiben , die selbst mehreren Puffern im Framebuffer zugeordnet werden . Daher müssen Sie angeben, welche Ausgabe an welche Fragmentausgabefarbe gesendet wird.
Dieser Prozess beginnt mit dem Wert des Fragmentausgabestandorts. Es ist sehr ähnlich zu den Vertex-Shader-Eingabepositionen eingestellt:
layout(location = 1) out secColor;
Es gibt auch die API-Funktionen glBindFragDataLocation
und glGetFragDataLocation
, die analog zu glBindAttribLocation
und sindglGetAttribLocation
.
Wenn Sie keine expliziten Zuweisungen vornehmen, weisen Implementierungen normalerweise eine Ihrer Ausgabevariablen Position 0 zu. Der OpenGL-Standard erfordert dies jedoch nicht dieses Verhalten , sodass Sie sich auch nicht darauf verlassen sollten.
Um fair zu sein, sollte Ihr Programm nicht verknüpft werden können, wenn Sie zwei Ausgaben verwendet haben, die keine unterschiedlichen Ausgabestellen erhalten haben. Was wahrscheinlich passiert ist, war, dass Ihr Compiler den optimiert hat, an den Sie nicht geschrieben haben, sodass er es irgendwie vergessen hat, als es an der Zeit war, nach Linkerfehlern zu suchen.