Unlimited WordPress themes, graphics, videos & courses! Unlimited asset downloads! From $16.50/m
Advertisement
  1. Game Development
  2. Aesthetics

Gamma-Korrektur und warum sie wichtig ist

by
Read Time:15 minsLanguages:

German (Deutsch) translation by Katharina Grigorovich-Nevolina (you can also view the original English article)

Wenn Sie ein Spieleentwickler sind, haben Sie wahrscheinlich von den Begriffen Gamma und Gamma-Korrektur gehört. Sie können oder können nicht wissen, was sie bedeuten, aber sie sollten nicht leichtfertig entlassen werden.

Spieleentwickler neigen dazu, Gamma zu ignorieren, da seine Effekte subtil genug sind, um durch Anpassen von Lichtintensitäten, Spiegelintensitäten und dergleichen annähernd korrigiert zu werden. Um jedoch eine realistische Bildqualität mit realistisch aussehender Beleuchtung zu erzielen, ist es wichtig, den Gammawert und die erforderlichen Schritte zu verstehen seine Präsenz in der digitalen Bildgebung zu umgehen, um die bestmögliche Qualität zu erhalten. Die Anwendung der richtigen Gammakorrektur ist eine der mühelosesten Möglichkeiten, um das Erscheinungsbild Ihrer Echtzeit-3D-Grafiken radikal zu verbessern.

Einführung: Funktionsweise von Monitoren

Die CRT-Monitore, die ursprünglich für Computerbildschirme verwendet wurden, haben eine merkwürdige Eigenschaft: Die Farbantwort auf ihren Bildschirmen ist in Bezug auf die von der Grafikkarte übergebenen Rohwerte nicht linear.

Nichtlinear bedeutet in diesem Sinne, dass eine Erhöhung einer Ihrer Farbkomponenten um ein konstantes Verhältnis (z. B. wenn eine rote Komponente einer Farbe doppelt so hoch wird) nicht zu einer Erhöhung der vom Monitor emittierten Lichtintensität um führt das gleiche Verhältnis (das heißt, das vom Bildschirm emittierte rote Licht ist nicht doppelt so hoch).

Die Farbantwort eines CRT-Monitors ist tatsächlich eine exponentielle Funktion. (Wie in der gesamten Physik ist dies viel komplexer als wir beschreiben, aber der Einfachheit halber bleiben wir bei dieser Annahme.) Das heißt, die Funktion EmittedLight(C), wobei C ein Farbkomponentenwert (rot) ist , grün oder blau) im Bereich von 0 (kein Licht) bis 1 (volle Lichtintensität), wird C auf eine gewisse Leistung γ angehoben.

Diese Zahl γ wird als Gamma-Exponent oder einfach als Gamma bezeichnet. Typische Gammawerte reichen von 2.0 bis 2.4, und wenn es sich um Gamma im allgemeinen Sinne handelt, wird ein Wert von 2.2 als Kompromiss vereinbart, und viele neuere Monitore sind so konzipiert, dass sie einen Gammawert von genau 2.2 haben

In einem gängigen Szenario mit Gamma = 2,2 zeigt der Monitor auf diese Weise tatsächlich die Farbintensitäten Ihres Spiels an (grüne Kurve). Die gepunktete rote Linie zeigt, wie ein linearer Monitor die gleichen Intensitäten anzeigen würde.

In der Praxis bedeutet dies, dass Schwarzweiß auf dem Bildschirm unverzerrt angezeigt wird (weil Null, die auf eine Potenz angehoben wird, Null ist und Eins, die auf eine Potenz angehoben wird, Eins ist), aber alle dazwischen liegenden Werte werden ohne zuverlässige Wahrnehmungsmethode verzerrt Dies geschieht nur durch Beobachten.

Wenn Sie beispielsweise eine Farbe anzeigen, die angeblich zweimal dunkler als Schwarz ist, d.h. RGB (0.5, 0.5, 0.5), wird sie bei einem gemeinsamen Gammawert von 2.2 tatsächlich weniger als viermal dunkler angezeigt , da 0.5 auf 2.2 erhöht ist, liegt bei 0.22. Dies ist natürlich nicht das, was Sie beabsichtigen, und dies ist nicht nur bei CRT-Monitoren der Fall: LCDs verfügen zwar nicht ungewollt über diese Eigenschaft, sind jedoch so konzipiert, dass sie mit ihren älteren Gegenstücken kompatibel sind, und zeigen daher Ihre Farbwerte so gestreckt an.

Da außerdem rote, grüne und blaue Komponenten unabhängig voneinander behandelt werden, können die beabsichtigten Farbtöne von Bildern leicht entstellt werden, da die Intensitäten der drei Farbkomponenten nicht gleichmäßig skalieren. Was passiert, wenn Sie den Farbwert RGB (1, 0.5, 0.5) anzeigen? Die rote Komponente bleibt bei 1, die anderen fallen jedoch auf die Hälfte ihrer Werte ab, wodurch sich der Farbton vollständig ändert.

Die zweite Farbe wurde von der ersten durch Anwenden der von Monitoren verwendeten nichtlinearen Skala erhalten. Beachten Sie, dass nicht nur die Helligkeit der Farbe, sondern auch ihre Sättigung von dieser Transformation beeinflusst wurde.

Nachdem wir gesehen haben, welche Auswirkungen diese Monitoreigenschaft auf die dem Monitor zugewiesenen Farbdaten hat, können wir sehen, welche Schritte es gibt, um sie zu bekämpfen.

Was ist Gamma-Korrektur?

Bei der Gamma-Korrektur wird die unglückliche Arbeit des Monitors rückgängig gemacht. Durch die Gammakorrektur eines Bildes werden die Farbintensitäten im Wesentlichen auf 1/gamma erhöht. Wenn der Monitor wiederum den Wert auf gamma erhöht, werden diese aufgehoben, und das Ergebnis ist die Farbe, die ursprünglich angezeigt werden sollte.

(Denken Sie daran, dass A, das auf B und dann auf C erhöht wird, dasselbe ist wie A, das auf B×C erhöht wird. Aus diesem Grund werden diese Operationen abgebrochen, da gamma × (1/gamma) 1 ist.)

Da der durchschnittliche Benutzer seinen Monitor nicht auf eine lineare Reaktion kalibriert, werden viele Bilder, auf die er trifft, so korrigiert, dass er den Unterschied nie spürt. Konventionell werden die meisten Bilddateien im Internet im sogenannten sRGB-Farbraum verteilt. Dies bedeutet, dass die ursprünglichen, beabsichtigten Farbwerte vor dem Einfügen in Dateien grob auf 1/2.2 angehoben werden (obwohl komplexere Gleichungen erforderlich sind) Platz in der Realität). Dies stellt sicher, dass alle Benutzer mit herkömmlichen Displays die echten Farben sehen. Scanner, Kameras und viele digitale Bildbearbeitungsgeräte berücksichtigen dies und korrigieren ihre Ausgabe für Sie, wenn Sie in herkömmlichen Bildformaten speichern.

Dieses Bild zeigt die Zuordnung der von der Grafikkarte an den Monitor gesendeten Farbintensitäten und der vom Monitor angezeigten Intensitäten.

Schauen Sie sich das obige Bild an. Wenn wir Gamma nicht berücksichtigen, ist die Kurve exponentiell (untere grüne Kurve). Wenn wir eine Gamma-Korrektur durchführen, ist die tatsächliche Reaktion linear, wie es sein sollte. Zum Vergleich zeigt das Bild auch, wie das Diagramm aussieht, wenn wir eine Gammakorrektur durchführen, der Monitor jedoch tatsächlich eine lineare Reaktion aufweist. In diesem Fall werden die Intensitäten in umgekehrter Weise verzerrt, und wir können sehen, dass, wenn ein nichtlinearer Monitor sie wiederum verzerrt, dies aufhebt und wir eine gerade Linie erhalten.

Wann muss ich mir Sorgen machen?

Bisher haben wir die Theorie hinter diesen Phänomenen erklärt - sicher, Monitore sind nicht linear und die meisten Bilder werden korrigiert, damit sie auf diesen Monitoren richtig aussehen, aber was scheint das Problem zu sein? Warum sollte ich mich als aufstrebender 3D-Spieleentwickler mit Gammakorrektur befassen und etwas anderes tun, als nur darüber Bescheid zu wissen?

Die Antwort ist einfach: Solange Bilder nur zur Anzeige erstellt werden, besteht das Problem nicht einmal. Sobald Sie jedoch wollen, dass ein Programm etwas mit diesen Bildern macht (sie skalieren, als Texturen verwenden, was auch immer), müssen Sie dafür sorgen, dass das Programm weiß, dass die Werte nicht real sind und nur korrigiert werden, damit sie auf einem Monitor real aussehen.

Dies geschieht insbesondere in einem Renderer, wenn Texturabbildungen wie diffuse Oberflächen als Eingabe verwendet werden. Es werden Operationen an ihnen durchgeführt, wobei angenommen wird, dass ihre Farbwerte die Lichtintensitäten genau wiedergeben; das heißt, unter der Annahme einer linearen Entsprechung mit realen Phänomenen, die sie darstellen.

Dies ist jedoch ein grundlegender Fehler: Wenn Sie Farbwerte summieren möchten und diese gammakorrigiert sind (auf 1/gamma erhöht), erhalten Sie die falschen Werte. Es braucht kein mathematisches Genie, um zu erkennen, dass A, das auf 1/gamma erhöht wurde, plus B, das auf 1/gamma erhöht wurde, nicht gleich (A+B) ist, das auf 1/gamma erhöht wurde. Das Problem tritt auch auf, wenn ein Renderer einige Werte ausgibt, z. B. wenn er Lichtbeiträge ausgibt: Wenn er zwei Lichtbeiträge summiert, aber nicht weiß, dass das Ergebnis bei Anzeige auf dem Bildschirm auf Gamma angehoben wird, hat er falsche Werte erzeugt.

Und genau hier tritt das Problem auf: Wann immer ein Renderer annimmt, dass die Farben, die er erhält, linear mit realen Phänomenen übereinstimmen, wenn dies nicht der Fall ist, oder annimmt, dass die Farben, die er ausgibt, linear mit den Lichtintensitäten auf dem Bildschirm übereinstimmen, wenn dies nicht der Fall ist, hat er einen schwerwiegenden Fehler begangen, der sich auf das Aussehen und die Wirkung der von ihm erzeugten Bilder auswirken kann.

Wenn Sie keinen der Fehler korrigieren, stellen Sie nicht sicher, dass die in den Renderer eingegebenen Eingabetexturfarben linear sind, und stellen Sie nicht sicher, dass das Ausgabebild des Renderers in Bezug auf den Bildschirm linear ist. Diese Bilder werden jeweils abgebrochen andere bis zu einem gewissen Grad, ähnlich wie sie sich gegenseitig aufheben, wenn vorkorrigierte JPEG-Dateien in einem Webbrowser angezeigt werden. Sobald Sie jedoch einige Zwischenberechnungen einbeziehen, die lineare Entsprechungen annehmen, ist Ihre Mathematik falsch.

(a) Keine Korrektur von Texturen und keine Korrektur des endgültigen Bildes, (b) keine Korrektur von Texturen, aber Korrektur des endgültigen Bildes, (c) Korrektur von Texturen, aber keine Korrektur des endgültigen Bildes, (d) Korrektur sowohl der Texturen als auch des endgültigen Bildes.

Erinnern Sie sich daran, was wir zuvor über das Ändern von Farbtönen gesagt haben - diese Tatsache kann Ihnen(manchmal) helfen, Nichtlinearität zu erkennen. Als Faustregel gilt: Wenn Sie Parameter linear anpassen (z. B. die Helligkeit von Lichtern in der Szene verdoppeln), ändert sich das resultierende Bild nicht nur in der Helligkeit, sondern auch in den Farbtönen (z. B. einem Bereich, der von a ausgeht) rötlich-orange Farbton in Richtung Gelb), dies bedeutet, dass höchstwahrscheinlich ein nichtlinearer Zwischenprozess stattfindet.

Dies kann bei Texturkarten auftreten, die aus verschiedenen Quellen abgerufen wurden - dem Internet, einer Digitalkamera, die in sRGB JPEG gespeichert ist, einem Scanner oder wenn die Textur auf einen Monitor gemalt wurde, der nicht explizit kalibriert wurde, um eine lineare Reaktion zu erzielen, oder nicht explizit danach korrigiert. Jede Berechnung, die auf diesen Texturkarten durchgeführt wird, ist falsch und weicht geringfügig von den theoretisch richtigen Werten ab. Dies ist bei Texturfiltern und Mipmaps sichtbar: Da beim Filtern bei der Mittelung von Farbwerten lineare Antworten angenommen werden, werden ausgeprägte Fehler angezeigt: Kleinere Texturen(entfernte) erscheinen merklich dunkler als größere (dh wenn sie näher bei Ihnen sind): Dies liegt daran, dass der Filteralgorithmus in der Ferne mehr Stichproben abtastet und ihre Nichtlinearität das Ergebnis stärker beeinflusst.

Die Beleuchtung leidet auch unter falschem Gamma: Lichtbeiträge zu Oberflächen summieren sich in der realen Welt und folglich in einem Renderer, aber das Summieren ist keine getreue Operation, wenn das Ergebnis nicht linear verzerrt ist. Wenn Sie komplexe Fragment-Shader haben, die eine ausgefeilte Beleuchtung ausführen, wie z. B. Streuung unter der Oberfläche oder HDR, werden die Fehler immer deutlicher, bis Sie sich tatsächlich fragen, was mit dem Bild nicht stimmt, anstatt ein unangenehmes Gefühl von "vielleicht irgendwie zu haben falsche Beleuchtung, aber es ist wahrscheinlich nur ich", was auch oft passieren kann. Das Abdunkeln der Texturen oder das Aufhellen der endgültigen Bilder um einen konstanten oder linearen Faktor hebt den Effekt nicht auf, da es sich auch um lineare Operationen handelt und Sie eine nichtlineare benötigen, um die im Monitor auftretende inhärente exponentielle Antwortkurve zu bekämpfen.

Wie kann ich es reparieren? 

Hoffentlich wissen Sie jetzt genau, was Gamma und Gamma-Korrektur sind und warum dies bei 3D-Echtzeitgrafiken so wichtig ist. Aber natürlich muss es eine Möglichkeit geben, diese Probleme zu beheben?

Die Antwort lautet "Ja", und das Korrigieren von Gamma ist eine ziemlich einfache Operation, bei der Sie nichts ändern müssen, außer ein paar Codezeilen hinzuzufügen, ohne zusätzliche Parameter, Intensität und Farbänderungen zu berücksichtigen, die Sie durchführen müssen, um die richtige Beleuchtung zu erhalten, wenn Sie haben Ihre Szenen so eingestellt, dass sie auf nichtlinearen Monitoren gut aussehen, ohne sie zu korrigieren.

Es gibt drei grundlegende Schritte, um sicherzustellen, dass Sie so lange wie möglich linear bleiben und die Korrektur am richtigen Punkt durchführen:

1. Stellen Sie sicher, dass Ihre Texturfarben richtig sind

Normalerweise sollten Sie die Quellbilder nicht so ändern, dass sie lineare Farben enthalten. Wenn die Farben für den typischen Monitor in 8-Bit-Farbfeldern gammakorrigiert werden, erhalten Sie die erforderliche zusätzliche Auflösung in dunkleren Bereichen, in denen das menschliche Auge empfindlicher auf Intensitätsschwankungen reagiert. Sie können jedoch sicherstellen, dass die Farbwerte linear sind, bevor sie Ihre Shader erreichen.

Normalerweise können Sie dies in OpenGL tun, indem Sie GL_SRGB8 anstelle von GL_RGB8 und GL_SRGB8_ALPHA8 anstelle von GL_RGBA8 an glTexImage2D() übergeben, wenn Sie eine Textur angeben. Dadurch wird sichergestellt, dass alle Werte, die von dieser Textur über einen Shader-Sampler gelesen werden, vom sRGB-Farbraum zurück in einen linearen korrigiert werden, genau das, was wir brauchen! Wenn Sie eine Rendering- oder Game-Engine verwenden, die das Laden von Texturen für Sie ausführt, wird dies möglicherweise berücksichtigt oder Sie müssen sie möglicherweise manuell angeben. Konsultieren Sie die Dokumentation der Bibliothek oder bitten Sie jemanden um Hilfe, wenn Sie sich nicht sicher sind.

Stellen Sie jedoch sicher, dass Sie dies nicht fälschlicherweise bei Bildern tun, die per Definition keine Farbinformationen darstellen und explizit in diesem Sinne gemalt wurden. Beispiele hierfür sind normale Karten, Reliefkarten oder Höhenkarten, die alle andere Daten als Farbe in den Farbkanälen einer Textur codieren und daher diese Art der Vorkorrektur wahrscheinlich nicht benötigen.

Aus der in diesem Artikel enthaltenen Demo (einige Parameter wurden aus Gründen der Übersichtlichkeit mit ihren tatsächlichen Werten ausgetauscht):

Dadurch wird die Textur in einen nicht korrigierten Farbraum geladen. Wenn sich die Daten in der Texturdatei jedoch im sRGB-Farbraum befinden, sollten wir den dritten Parameter in GL_SRGB8 ändern, was Folgendes ergibt:

Dadurch wird sichergestellt, dass OpenGL die Texturdaten korrigiert, wenn wir sie nachschlagen.

2. Stellen Sie sicher, dass Ihre Ausgabebildfarben richtig sind

Jetzt müssen Sie die Farbkorrektur auf die endgültigen Ausgabebilder Ihres Renderers anwenden. Stellen Sie sicher, dass Sie nur den endgültigen Framebuffer korrigieren, der auf dem Bildschirm angezeigt werden soll. (Berühren Sie nicht die Zwischenpuffer, die in andere Nachbearbeitungs-Shader eingegeben werden, da diese weiterhin mit linearen Werten arbeiten.)

Dies kann in OpenGL erfolgen, indem der Renderbuffer (der endgültige, nicht abtastbare Framebuffer) mit einer sRGB-Farbcodierung angegeben wird, indem GL_SRGB anstelle von GL_RGB als Parameter an glRenderbufferStorage() übergeben wird. Danach müssen Sie das Flag GL_FRAMEBUFFER_SRGB durch Aufrufen von glEnable setzen. Auf diese Weise werden Shader-Schreibvorgänge in sRGB-Puffer korrigiert, sodass sie direkt auf einem typischen Monitor angezeigt werden.

Wenn Sie eine Engine oder ein Framework verwenden, enthält diese wahrscheinlich eine Option, um einen sRGB-Framebuffer für Sie zu erstellen und ordnungsgemäß einzurichten. Auch hier können Sie die Dokumentation der Bibliothek konsultieren oder jemanden bitten, dies für Sie zu klären.

In der Demo verwenden wir die GLFW-Bibliothek, die uns eine einfache Möglichkeit bietet, einen sRGB-Framebuffer anzufordern. Insbesondere setzen wir einen Fenstertipp und weisen OpenGL später an, die Framebuffer-Operationen im sRGB-Bereich zu aktivieren:

3. Korrigieren Sie Ihre optimierten Lichtintensitäten und Farbparameter

Wenn dies kein Start eines neuen Projekts ist, besteht die Möglichkeit, dass Gamma-inkorrekte Beleuchtung und Filterung Ihren Tribut gefordert haben. Vielleicht haben Sie Ihre diffusen Reflexionsfarben, Lichtintensitäten und so weiter optimiert, um subtile Belästigungen auszugleichen, die Ihnen das Vernachlässigen von Gamma gebracht hat.

Sie müssen diese Werte noch einmal durchgehen und sie so anpassen, dass sie wieder richtig aussehen. Diesmal sehen Ihre Szenen jedoch natürlicher aus, da die Beleuchtung die Umstände der realen Welt genauer darstellt. Ecken sehen nicht zu dunkel aus, sodass Sie den Lichtern keine größere Intensität verleihen müssen (wodurch die Beleuchtung hellerer Objekte beeinträchtigt wird, die dann für diese Lichtmenge in der Szene künstlich hell aussehen).

Dies wird sich auszahlen: Wenn Sie Ihre Parameter erneut überprüfen, um eine natürliche Umgebung mit Gammakorrektur zu schaffen, können Sie Ihren Benutzern eine Erfahrung und Helligkeitsverteilung bieten, die genau richtig für ihre Augen aussieht und so gewohnt und empfindlich ist, wie Licht im wirklichen Leben funktioniert .

Demo

Diesem Artikel ist eine kleine OpenGL 3.3-Demo beigefügt, die eine einfache Szene mit einigen Texturen zeigt, die von zwei beweglichen Lichtquellen beleuchtet werden. Sie können zwischen verschiedenen Szenarien wechseln: Nicht Texturen korrigieren, sondern das endgültige Bild korrigieren; Texturen korrigieren, aber das endgültige Bild nicht korrigieren; beides korrigieren (d.h. alles richtig machen); und auch nicht korrigieren (effektiv einen doppelten Fehler machen).

Die Demo ist in C++ (mit zwei GLSL-Shadern) geschrieben und verwendet tragbare GLFW- und GLEW-Bibliotheken, sodass sie auf einer Vielzahl von Plattformen ausgeführt werden sollte. Der Quellcode ist voller Kommentare, sodass Sie jeden Aspekt dieser kurzen Anwendung erkunden können.

Die Demo in Aktion.

Verwenden Sie die Taste 1 auf Ihrer Tastatur, um zwischen der Korrektur von Texturen und der Nichtkorrektur von Texturen zu wechseln, und die Taste 2, um zwischen der Korrektur des Framebuffers und der Nichtkorrektur des Framebuffers zu wechseln. Um beide gleichzeitig zu durchlaufen, drücken Sie 3 - nützlich, um den Unterschied zwischen der vollständigen Vernachlässigung von Gamma (zwei Fehler, die sich größtenteils gegenseitig aufheben) und dem richtigen Vorgehen zu erkennen. Wenn die Demo startet, wird keine dieser Korrekturen durchgeführt. Drücken Sie also 3, um die Vorteile einer korrekten Gammakorrektur zu sehen.

Ich habe ein Microsoft Visual C++ 2013-Projekt, kompatible 64-Bit-Versionen der GLFW- und GLEW-Bibliotheken und eine ausführbare 64-Bit-Windows-Datei hinzugefügt. Sie können dies jedoch auf jeder Plattform mit GLFW- und GLEW-Unterstützung recht einfach kompilieren: Kompilieren Sie einfach main.cpp und loader.cpp und verknüpfen Sie sie mit diesen beiden Bibliotheken. Unter Linux sollten Sie diese Bibliotheken über Ihren Paketmanager installieren und -lglew -lglfw an g++ übergeben. (Bitte beachten Sie, dass dies nicht auf anderen Betriebssystemen als Windows getestet wurde, aber es sollte funktionieren. Wenn Sie auf Probleme stoßen, lassen Sie es mich bitte in den Kommentaren wissen und ich werde sie so schnell wie möglich beheben.)

Wie Sie beim Ausführen der Demo sehen können, sind die Effekte selbst bei einem einfachen Modell und einer einfachen Szene wie dieser deutlich spürbar. In diesem einfachen Fall könnten Sie natürlich die Shader-Parameter anpassen, damit das Bild gut aussieht, wenn es nicht korrigiert wird. Sobald Sie jedoch anfangen, Komplexität in Ihren Szenen aufzubauen, wird der Unterschied einfach zu sichtbar sein, um ihn jemals auf diese Weise auszugleichen.

Schlussfolgerung

In diesem Artikel haben wir Begriffe wie Gamma, Gamma-Korrektur, nichtlineare Ein- und Ausgänge und nichtlineare Mathematik behandelt. Hoffentlich habe ich es geschafft, Sie davon zu überzeugen, dass Sie sich jetzt Gedanken über die Gamma-Korrektur machen sollten, wenn Sie dies bisher vernachlässigt haben, und wenn Sie vor der Begegnung mit diesem Artikel vorsichtig mit Gamma umgegangen sind, hoffe ich nur, dass es Ihnen etwas Neues gibt winzige Informationen, mit denen das Problem angegangen werden kann.

Wir haben vor allem gelernt, wie Sie Probleme beheben können, die auftreten, wenn Sie Farbwerte falsch bearbeiten, vorausgesetzt, sie sind linear, und wir haben häufige Fallstricke und Symptome untersucht, die auftreten, wenn Sie diesen wichtigen Aspekt der Computergrafik vernachlässigen.

Ich hoffe, Sie hatten Spaß und haben beim Lesen dieses Artikels etwas Neues gelernt. Bis zum nächsten Mal!

Advertisement
Advertisement
Looking for something to help kick start your next project?
Envato Market has a range of items for sale to help get you started.