In letzter Zeit habe ich versucht, meinen openGl Render zu bereinigen. Ich hatte diese Artefakte jetzt schon eine Weile, habe aber nie wirklich darauf geachtet. Hier ist ein Screenshot:
Ich war nicht in der Lage herauszufinden, was falsch ist nach ein wenig Forschung. Ich benutze OpenGl unter OSX, aber ich habe es auf anderen Systemen versucht und die gleichen Artefakte auftreten.
Was Sie erleben, ist der begrenzte dynamische Bereich von 8 Bit pro Kanal Farbraum. Ein einfacher Graustufengradient, d. H. R = B = G auf einem Framebuffer mit 8 Bit pro Kanal, kann nur 2 ^ 8 = 256 verschiedene Werte haben. Wenn Sie zwischen ähnlichen Werten (wie in Ihrem Bild) über einen großen Bereich wechseln, ist das Ergebnis ein Bandbereich mit geringem Dynamikbereich.
Der einzige Weg, dies zu überwinden, ist die Berechnung des Gradienten mit einer größeren Anzahl von Bits. Zum Anzeigen des Bildes auf einem Bildschirm mit niedriger Dynamik können Sie Dithering verwenden.
Wie von datenwolf erläutert, besteht das Problem darin, Subpixelwerte auf einen 8-Bit-Bereich zu runden und keine Op-Implementierung durchzuführen von GL_DITHER
bei den meisten OpenGL-Implementierungen. Um dies zu erleichtern, können Sie Dithering als Postprocessing-Schritt durchführen (eine weitere Möglichkeit besteht darin, dies direkt im Fragment-Shader für jedes relevante Primitiv zu tun). Beachten Sie jedoch, dass einige Voraussetzungen für die OpenGL-Implementierung erforderlich sind:
Unterstützen Sie hochpräzise interne Texturformate: Sie müssen Zugriff auf zusätzliche Präzision der resultierenden Farben haben. Je mehr Extra-Präzision, desto feiner die Variation der Farben, die Sie glatt rendern können. Die Optionen sind:
Gleitkomma-Texturen (erfordert GL_ARB_texture_float
oder OpenGL 3.0+) llike RGBA32F
, RGBA16F
oder R11F_G11F_B10F
breiter als 8-Bit-Integralformate wie RGB10_A2
oder RGBA16
FBO ( GL_ARB_framebuffer_object
): Sie möchten nachbearbeiten.
NPOT-Texturen: Die meisten Bildschirme haben nicht-zwei Dimensionen; Es ist noch wichtiger für den Fenstermodus.
GLSL: Sie möchten einen Shader verwenden. Eine andere Option ist GL_ARB_fragment_program
.
Richtige Unterstützung für hochpräzise Framebufferkonfigurationen. Wenn Sie das integrale Texturformat wie RGBA16
wählen, kann es im Stillen durch z.B. RGBA8
(siehe Spezifikation von TexImage2D
mögliche interne Formate).
Bei all dem ist hier eine Demo mit den oben genannten Features (und Fließkomma-Texturen, um sicher zu sein, dass das Resultat möglich ist), um den ditherless beleuchteten grauen Würfel mit dem geditherten zu vergleichen. Beachten Sie, dass es standardmäßig für Monitore, die selbst Dithering durchführen, schlechte Ergebnisse liefert, da sie tatsächlich 6bpp statt 8bpp sind. Für 6bpp definieren Monitore MONITOR_6_BPP
beim Kompilieren dieses Codes.
Tags und Links opengl