Seite 1 von 1

OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 14.07.2020, 16:20
von smurfer
Hallo zusammen,

ich rendere in eine Textur mittels FBO, der Viewport und die Texturkoordinaten werden an die Fenstergröße angepasst, sobald eine Größenänderung stattfindet. Sprich, der relevante Texturausschnitt hat immer die (Pixel-) Auflösung des Fensters.

Wenn ich nun jene Textur auf ein Quad/zwei Dreiecke/ein übergroßes Dreieck mappe und dieses texturierte Mesh in den finalen Framebuffer rendern möchte, gibt es eine bevorzugte 2D-Projektion?
  • Jedes mal die Projektion auf die Fenstergröße anpassen, jedesmal die Koordinaten des Meshes ändern
  • Immer auf ein "Einheitskoordinatensystem" [-1, +1] rendern, und das (statische) Mesh in einem VBO auf der GPU belassen
    • Jede andere beliebige Projektion (z.B. 1347x612) statisch beibehalten
Ich denke es sollte bei gängigen Auflösungen keine Genauigkeitsunterschiede geben, oder?! Übersehe ich etwas, oder ist es beliebig?

Danke, beste Grüße

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 14.07.2020, 17:37
von xq
Das klingt für mich nach Postprocessing. Schau mal gl_FragCoord und texelFetch an.

Ansonsten kannst du ein Quad mit der Größe -1,-1 ... 1,1 rendern, dies wäre (ohne) Projektion immer bildschirmfüllend

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 14.07.2020, 18:35
von smurfer
Danke für die schnelle Antwort.

Vielleicht habe ich mich etwas missverständlich ausgedrückt, denn texelFetch und glFragCoord nutze ich recht häufig und hätte sie dort nicht assoziiert.

Frage war maßgeblich, ob statt des von dir genannten Quads ein Vorteil bestünde, wenn ein "0, 0... Breite, Höhe" Quad und die entsprechende Projektion verwendet wird, damit es bildschirmfüllend ist. Dann müssten die Vertices des Quads allerdings immer aktualisiert werden.
Alternativ zum dagegen statischen Quad - 1,-1... 1,1 kann natürlich auch jede andere Projektion mit entsprechendem Quad verwendst werden, z. B. - 100, - 100... 100, 100. Hier hatte ich überlegt, ob das einen Einfluss auf die Genauigkeit hat.

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 14.07.2020, 19:12
von smurfer
Noch etwas zum Hintergrund: Ich berechne eine 2D-Fluiddynamik auf der GPU, d.h. die Parameter des Grids werden in Texturen verwaltet und dabei per texelFetch ausgelesen, bis dahin ist alles diskret. Über die resultierende Fluid-Textur wird die (2D-)Szene gerendert, plus ein wenig Postprocessing, wiederum per FBO in eine Textur. Diese, sowie eine etwaige Weitere bei Splitscreen, werden in den finalen Framebuffer gerendert (der diskutierte Quad, 2+ bei Splitscreen).

Ich möchte bei diesen Schritten keine Präzision verlieren. Auch wenn es mit den +0.375px für Pixelgenauigkeit bei OGL zwar irgendwie "pixel perfect" möglich ist, verliere ich bei einer etwas größeren Pipeline den Überblick. An einer Stelle habe ich bei kleinen Objekten bereits unerwartetes Aliasing, d. h. irgendwo in der Kette passt die Abtastung/Genauigkeit nicht.

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 14.07.2020, 19:18
von Spiele Programmierer
smurfer hat geschrieben: 14.07.2020, 18:35 Frage war maßgeblich, ob statt des von dir genannten Quads ein Vorteil bestünde, wenn ein "0, 0... Breite, Höhe" Quad und die entsprechende Projektion verwendet wird, damit es bildschirmfüllend ist.
Ich denke nicht.
Das bereits erwähnte gl_FragCoord liefert die Pixel-Koordinaten. Ansonsten kann man auch jederzeit umrechnen.
smurfer hat geschrieben: 14.07.2020, 18:35Dann müssten die Vertices des Quads allerdings immer aktualisiert werden.
Warum? Diese sehr einfache Transformationen kannst du doch prima im Shader machen.

Für ein einziges Screen-Space-Quad (oder Triangle) spare ich mir die Buffer sogar meistens ganz und wähle die Eckpunkte lieber einfach direkt aus einem const-Array im Shader-Code mit gl_VertexId.
smurfer hat geschrieben: 14.07.2020, 18:35Hier hatte ich überlegt, ob das einen Einfluss auf die Genauigkeit hat.
Ne, das ist egal. Die floats sind Gleitkommazahlen und die Größenordnung spielt keine Rolle. Es verschiebt sich nur der Exponent.

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 14.07.2020, 19:31
von smurfer
Das bereits erwähnte gl_FragCoord liefert die Pixel-Koordinaten. Ansonsten kann man auch jederzeit umrechnen.

Gut, die Pixelkoordinaten benötige ich ja gar nicht, mir war nur wichtig, das "pixel perfect" besser nachvollziehen zu können (siehe mein letzter Post). Nicht missverstehen, ich möchte nicht auf Teufel-komm-raus pixel perfect sein, jedoch das Aliasing weitgehend verhindern, bzw. zusätzliche Ungenauigkeiten vermeiden.
Für ein einziges Screen-Space-Quad (oder Triangle) spare ich mir die Buffer sogar meistens ganz und wähle die Eckpunkte lieber einfach direkt aus einem const-Array im Shader-Code mit gl_VertexId.
Guter Hinweis!
Ne, das ist egal. Die floats sind Gleitkommazahlen und die Größenordnung spielt keine Rolle. Es verschiebt sich nur der Exponent
Okay, so dachte ich mir das auch, danke für die Bestätigung.

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 15.07.2020, 08:42
von Schrompf
Es gibt übrigens Leute, die ein wirklich großes Einzeldreieck anstatt eines Quads nehmen, weil an der Kante zwischen den Dreiecken die FragmentShader viel leer laufen. Andere Leute propagieren ein dichtes Netz aus Quads, weil es die Cache-Lokalität verbessert, und berichten von ~10% Performance-Gewinn.

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 15.07.2020, 09:02
von Krishty
Schrompf hat geschrieben: 15.07.2020, 08:42Es gibt übrigens Leute, die ein wirklich großes Einzeldreieck anstatt eines Quads nehmen, weil an der Kante zwischen den Dreiecken die FragmentShader viel leer laufen.
… als ich’s 2008 getestet habe, wurde das Einzeldreieck allerdings zu zwei Dreiecken geclippt und hatte wieder eine Kante in der Mitte :)

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 15.07.2020, 09:14
von smurfer
@Schrompf und @Krishty:

Tatsächlich habe ich im Eröffnungspost das "übergroße Dreieck" erwähnt, weil ich mich an Krishtys Post zu dem Thema erinnerte :). Für Splitscreen dann aber wahrscheinlich doch ungeeignet (Edit: obwohl, ginge doch mit entsprechend zwei übergroßen Dreiecken).

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 15.07.2020, 10:14
von Krishty
Hier geht echt nichts verloren :D

Noch zu Klarstellung: Auch wenn das übergroße Dreieck nicht die versprochene höhere Auslastung bringt, macht es immerhin den Code ein wenig kürzer (drei Punkte erzeugen statt vier). Ich empfehle das also durchaus :)

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 15.07.2020, 11:22
von smurfer
Und bei Splitscreen nur 4 statt 6 :-D

Mir ist gerade aufgefallen, dass es natürlich auch bei dynamischem (und vielmehr mitunter "schräg" getrenntem) Splitscreen funktioniert. Hatte das bislang deswegen irgendwie immer ausgeblendet.

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 15.07.2020, 13:34
von Spiele Programmierer
Hab hier einen relativ aktuellen Vergleich gefunden: https://cginternals.com/en/blog/2018-01 ... ngles.html
Das Ergebnis: Mit einem Dreieck ist es tendentiell schneller, aber nur auf einem Intel-System ist der Unterschied wesentlich.

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 15.07.2020, 13:51
von Krishty
Das Update ist auch interessant: Wenn zwei Dreiecke gerendert werden, flusht zwischendurch der Cache des Rasterizers. Es sei denn, die beiden Dreiecke sind aus dem Clipping eines gemeinsamen Ursprungs-Dreiecks entstanden – dann nicht.

What a time to be alive!

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 15.07.2020, 22:14
von smurfer
Das ist fast schon was für den Antijammer-Thread:

Ich nutze jetzt ein übergroßes Dreieck mit den konstanten Vertices innerhalb des Shaders d.h. ohne Vertexbuffer. Splitscreen sind keine zwei Framebuffer mehr, sondern einer mit verändertem Viewport, es bleibt also ein großes Dreieck auch bei Splitscreen, so dass es immer noch möglich ist, die konstanten Vertices im Shader zu nutzen. Da die dem FBO zugrunde liegende Textur von statischer Größe ist, müssen sowohl bei Splitscreen als auch bei Größenänderungen des Fensters (oder beidem) die Texturkoordinaten des "großen Dreiecks" angepasst werden. Dies passiert über einen einzelnen float-Uniform. Ah, schön schlank und performant!

Danke allen soweit für die Ideen.

Re: OpenGL -- orthographische Projektion, RTT, Größenänderung

Verfasst: 15.07.2020, 22:30
von smurfer
Hier der Vertex-Shader-Code zur Vervollständigung (vertikaler Splitscreen):

Code: Alles auswählen

uniform float u_tex_scale_x;

out vec2 v_tex;

const vec2 pos[3] = vec2[]
(
    vec2(-1.0, -1.0),
    vec2( 3.0, -1.0),
    vec2(-1.0,  3.0)
);

const vec2 tex[3] = vec2[]
(
    vec2(0.0, 0.0),
    vec2(2.0, 0.0),
    vec2(0.0, 2.0)
);

void main()
{
    v_tex = vec2(u_tex_scale_x*tex[gl_VertexID].x, tex[gl_VertexID].y);
    gl_Position = vec4(pos[gl_VertexID], 0.0, 1.0);
}