Was ist die beste Möglichkeit, Vollbild-Texturen in einem Fragment-Shader, zum Beispiel der G-Puffer in einem verzögerten Renderer, oder die Szene Textur in einem Postprozess-Shader?Der beste Weg, um eine Fullscreen-Textur zu sampeln
Im Moment habe ich die folgenden zwei Arten verwenden:
Geben Sie die Bildschirmgröße an den Shader als einheitliche und berechnen (u, v) von
gl_FragCoord
:vec2 texCoord = gl_FragCoord.xy/vScreenSize; vec3 c = texture(tex, texCoord).rgb;
Does nicht scheinen ideal zu sein, da eine Aufteilung erforderlich ist und die Bereitstellung des Shaders mit der Bildschirmgröße mühsam ist.
Convert
gl_FragCoord.xy
in einivec
und verwendentexelFetch
:vec3 c = texelFetch(tex, ivec2(gl_FragCoord.xy), 0).rgb;
auch nicht ideal, da die Umwandlung von
float
zuint
erforderlich ist.
Also gibt es einen besseren Weg? Ich möchte wirklich nur einen Puffer genau an der Stelle abtasten, an der mein Pixelshader gezeichnet wird.
// EDIT:
Ok, mit den Vorschlägen von interpoliert Textur-Koordinaten, die vom Vertex-Shader kommen ich es geschafft, den folgenden Code, um herauszufinden:
Vertex-Shader:
#version 150
uniform mat4 im_ModelViewProjectionMatrix;
in vec3 iv_Vertex;
noperspective out vec2 vVertCoord;
void main(void)
{
gl_Position = im_ModelViewProjectionMatrix * vec4(iv_Vertex, 1.0);
vVertCoord = (gl_Position.xy/gl_Position.w) * (0.5) + vec2(0.5);
}
Ich berechne grundsätzlich normalisierte Gerätekoordinaten (NDC) aus dem Clip Spac Stellen Sie die Position mit der perspektivischen Division ein und bilden Sie dann die NDCs (die von [-1,1] reichen) in das Intervall [0,1] ab. Dies funktioniert hervorragend für Vollbild-Quads (auch ohne die perspektivische Teilung, weil Koordinaten so einfach sind). Die willkürliche Geometrie, die ich in meinem Deferred Renderer als Lichtgeometrie zeichnen muss, hat jedoch einige Probleme. In dem Vertex-Shader-I-Ausgang vVertCoord
als Farbe für Rot = x und grün = y:
#version 150
noperspective in vec2 vVertCoord;
out vec4 colorOut;
void main(void)
{
colorOut = vec4(vVertCoord.x, vVertCoord.y, 0, 1);
}
Dies ist das Ergebnis, wenn ich in einer Punkt-Licht-Kugel bin, alles sieht gut aus (die schwarzen Linien wiedergegeben werden absichtlich):
wenn ich jedoch näher an der Licht-Geometrie bewegen ist dies das Ergebnis:
Was macht der rote Fleck in der oberen linken Ecke dort? Sie möchten die Ergebnisse nicht in Echtfarben sehen, da die Debugging-Farben deaktiviert sind, da es sich um einen LSD-Trip handelt. Wenn Sie die Kamera bewegen, wird alles verzerrt. Berührt sich diese Genauigkeit? Beachten Sie, dass alles in Ordnung ist, wenn ich stattdessen gl_FragCoord im Pixelshader verwende.
Gibt es einen besonderen Grund, warum Ihre Texturkoordinaten auf gl_FragCoord basieren und kein normales interpolierte Attribut? Im ersten Beispiel würde dies die Notwendigkeit für die Teilung bereits beseitigen. p.s. Anstelle von vScreenSize können Sie den reziproken Wert der Bildschirmgröße haben (indem Sie die Division in eine Multiplikation umwandeln). –
Wahrscheinlich möchten Sie das letztere nicht, da dies die Möglichkeit der Strukturfilterung ausschließt. Während Sie vielleicht denken, dass Ihnen das nicht wirklich wichtig ist, kann es in einer Deferred-Shading-Engine nützlich sein, die G-Buffer-Generierung und -Schattierung mit unterschiedlichen Auflösungen durchzuführen (besonders auf Low-End-Hardware, die normalerweise ziemlich voll ist). –