Ich versuche zu verstehen, was HDR ist und wie es funktioniert.
Ich verstehe die Grundkonzepte und habe eine kleine Vorstellung davon, wie es mit D3D / hlsl implementiert wird.
Trotzdem ist es ziemlich neblig.
Angenommen, ich rendere eine Kugel mit einer Textur der Erde und einer kleinen Punktliste von Eckpunkten, die als Sterne fungieren sollen. Wie würde ich dies in HDR rendern?
Hier sind ein paar Dinge, die mich verwirren:
Ich vermute, ich kann nicht jedes Basisbildformat für die Textur verwenden, da die Werte in einem Shader auf [0, 255] und auf [0, 1] beschränkt wären. Gleiches gilt für den Rückpuffer, ich nehme an, das Format muss ein Gleitkommaformat sein?
Was sind die anderen Schritte? Sicherlich muss es mehr als nur die Verwendung von Gleitkommaformaten geben, um ein Rendering-Ziel zu rendern und dann etwas Bloom als Nachbearbeitung anzuwenden? (wenn man bedenkt, dass die Ausgabe ohnehin 8bpp sein wird)
Was sind die grundlegenden Schritte für HDR? Wie funktioniert es ? Ich kann anscheinend keine guten Papiere / Artikel finden, die den Prozess beschreiben, außer diesem , aber es scheint ein wenig über die Grundlagen zu gehen, also ist es verwirrend.
Technisch bedeutet HDR lediglich, einen größeren Bereich möglicher Werte für Ihre Grafiken zu verwenden. Normalerweise sind Sie auf 256 diskrete Werte für die Kanäle Rot, Grün und Blau beschränkt. Wenn Sie also zwei Objekte haben, eines doppelt so hell wie das andere und ein drittes, das 10.000-mal heller ist als das erste, gibt es kein Auf diese Weise können Sie alle 3 in der gleichen Szene korrekt darstellen - entweder machen Sie das helle Objekt nur 256x heller als das erste, oder Sie machen beide stumpfen Objekte komplett schwarz (verlieren den Kontrast zwischen ihnen) und dann ist das helle Objekt unendlich heller als sie beide.
Dies lässt sich leicht beheben, indem Gleitkommawerte für die Rot / Grün / Blau-Werte verwendet werden. Jetzt haben Sie jedoch das Problem, wie Sie dies auf einem Grafikgerät anzeigen können, das nur eine feste Anzahl von diskreten Werten pro Kanal verarbeitet (z. B. 256). . Der zweite Teil des Problems ist also, wie Sie Ihre Gleitkommawerte auf den begrenzten Bereich zurückführen können. Die einfache Lösung besteht darin, alle Werte proportional in den diskreten Bereich zu skalieren. Dies würde jedoch bedeuten, dass der Rest des Bildschirms durch 1 sehr helles Pixel schwarz wird. Manchmal ist dies das, was Sie möchten, manchmal nicht - siehe CiscoIPPhone-Tonzuordnung Link für Beispiele, wie Sie dies angehen können.
Im Allgemeinen müssen Ihre Texturen nicht in einem neuen Format gespeichert werden. Wenn die Beleuchtung auf sie angewendet wird, müssen Sie in der Lage sein, größere Werte aufzunehmen. Offensichtlich jedoch, wenn Sie Lichtquellen in eine Textur eingebrannt haben - z. ein sternenklarer Hintergrund - möglicherweise möchten Sie dort ein Format mit höherer Auflösung. Oder lassen Sie den Shader die Werte solcher Materialien skalieren, wenn die Zeit gekommen ist, sie zu rendern.
quelle
Computer stellten traditionell jedes Pixel auf dem Bildschirm als nur 24 Bit im Speicher dar: 8 für Rot, 8 für Grün und 8 für Blau. Das sind fast genug Bits, die ein Mensch nicht bemerken würde, wenn Sie mehr hinzufügen, und das 8-Bit-Byte ist sehr praktisch für Mikroprozessoren, also ist es das, was stecken bleibt.
Während 8 Bit fast genau genug sind, um ein Bild anzuzeigen , ist es definitiv nicht genau genug, um ein Bild zu berechnen . Bei der Bildberechnung sind an verschiedenen Stellen mindestens 32 Bit Genauigkeit erforderlich.
Aus diesem Grund berechnen Pixel-Shader Farben mit einer 32-Bit-Genauigkeit, auch wenn Sie ein Bild mit einer 8-Bit-Genauigkeit rendern. Andernfalls könnten Sie beispielsweise einen Wert nicht durch 1000 teilen und ihn später mit 1000 multiplizieren, da das Teilen eines 8-Bit-Werts durch 1000 zu Null führt.
Bei 3D-Echtzeitgrafiken ist der Trend zu beobachten, dass alle Grafiken bis zum letztmöglichen Zeitpunkt eine Genauigkeit von> 8 Bit aufweisen. Zu diesem Zeitpunkt werden die> 8 Bit von Rot auf 8 Bit heruntergerechnet, und so weiter für Grün und Blau.
HDR bezieht sich auf das Rendern von Bildern mit einer Genauigkeit von mehr als 8 Bit. In modernen TV-Videospielen ist 16-Bit-Präzision die Norm, und dies könnte in Videospielen für die kommenden Jahre "genug" sein.
quelle
Ein Aspekt, von dem ich denke, dass er für HDR entscheidend ist, ist die korrekte Anwendung von Monitor-Gamma.
Der Monitor, den Sie betrachten, erzeugt Licht in Abhängigkeit von den Eingangspixeln. Sie können erwarten, dass ein Pixel mit dem Wert 255 (ungefähr) 255-mal mehr Licht erzeugt als ein Pixel mit dem Wert 1. Dies ist nicht der Fall. Mit einem Standard-Monitor-Gamma von 2,3 ist es 255 ^ 2,3-mal heller oder ungefähr 340000!
Jeder Produzent von Inhalten (Kamerahersteller) weiß das oder (wenn Sie Designer sind) Sie kompensieren es implizit.
Dies ist alles in Ordnung, wenn Sie nur Bitmaps rendern (nun ja, die meiste Zeit), aber wenn Sie sie als Texturen in einer 3D-Szene verwenden, ist es eine andere Geschichte. Wenn Sie die Interaktion mit Licht korrekt modellieren möchten, sollten Sie in der gesamten Rendering-Pipeline lineare Lichtberechnungen verwenden. Das heisst
Korrigieren Sie Ihre Texturen für Gamma
rendern Sie alles mit linearem Licht (wo Sie aufgrund des hohen dynamischen Lichtbereichs viel Präzision benötigen),
Wenden Sie als letztes die inverse Gamma-Transformation des Monitors an, bevor Sie das Bild auf den Bildschirm stellen.
Wenn Sie diese Änderung an einer vorhandenen Szene mit vorhandenen Grafiken, Lichtern usw. vornehmen, müssen Sie wahrscheinlich viele Ihrer Lichtintensitäten und Texturen korrigieren, da diese so ausgewählt wurden, dass sie beim Rendern mit nichtlinearem Licht gut aussehen. Es ist also keine Funktion, die Sie einfach "einschalten" und erwarten können, dass alles einfach so besser aussieht.
quelle