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

Für Fragen zu Grafik APIs wie DirectX und OpenGL sowie Shaderprogrammierung.
Antworten
smurfer
Establishment
Beiträge: 195
Registriert: 25.02.2002, 14:55

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

Beitrag 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
Benutzeravatar
xq
Establishment
Beiträge: 1581
Registriert: 07.10.2012, 14:56
Alter Benutzername: MasterQ32
Echter Name: Felix Queißner
Wohnort: Stuttgart & Region
Kontaktdaten:

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

Beitrag 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
War mal MasterQ32, findet den Namen aber mittlerweile ziemlich albern…

Programmiert viel in ⚡️Zig⚡️ und nervt Leute damit.
smurfer
Establishment
Beiträge: 195
Registriert: 25.02.2002, 14:55

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

Beitrag 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.
smurfer
Establishment
Beiträge: 195
Registriert: 25.02.2002, 14:55

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

Beitrag 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.
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

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

Beitrag 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.
smurfer
Establishment
Beiträge: 195
Registriert: 25.02.2002, 14:55

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

Beitrag 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.
Benutzeravatar
Schrompf
Moderator
Beiträge: 4838
Registriert: 25.02.2009, 23:44
Benutzertext: Lernt nur selten dazu
Echter Name: Thomas Ziegenhagen
Wohnort: Dresden
Kontaktdaten:

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

Beitrag 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.
Früher mal Dreamworlds. Früher mal Open Asset Import Library. Heutzutage nur noch so rumwursteln.
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

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

Beitrag 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 :)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
smurfer
Establishment
Beiträge: 195
Registriert: 25.02.2002, 14:55

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

Beitrag 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).
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

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

Beitrag 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 :)
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
smurfer
Establishment
Beiträge: 195
Registriert: 25.02.2002, 14:55

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

Beitrag 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.
Spiele Programmierer
Establishment
Beiträge: 426
Registriert: 23.01.2013, 15:55

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

Beitrag 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.
Benutzeravatar
Krishty
Establishment
Beiträge: 8229
Registriert: 26.02.2009, 11:18
Benutzertext: state is the enemy
Kontaktdaten:

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

Beitrag 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!
seziert Ace Combat, Driver, und S.T.A.L.K.E.R.   —   rendert Sterne
smurfer
Establishment
Beiträge: 195
Registriert: 25.02.2002, 14:55

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

Beitrag 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.
smurfer
Establishment
Beiträge: 195
Registriert: 25.02.2002, 14:55

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

Beitrag 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);
}
Antworten