Das Floating-Point-Format im Detail
Teil 3 von 3 / 15. März 2004 / von aths / Seite 12 von 13
Floating Point - Wozu der Spaß?
Jetzt wollen wir anhand zweier Beispiele zeigen, wo FP-Formate denn nun in der Praxis nützlich sind. Zunächst die Frage nach Gamma-korrektem Rendering.
Röhren-Monitore haben eine nichtlineare Helligkeits-Wiedergabe. Mit der Gamma-Funktion kann man das einigermaßen ausgleichen, dazu sucht man einen passenden Parameter für die Gamma-Kurve. Ein Parameter von 1,0 heißt, dass nichts geändert wird. Hat der Monitor von sich aus eine Gamma-Charkteristik von 0,6, kann das durch die Gammakorrektur mit dem Parameter 1 / 0,6 = 1,67 wieder ausgeglichen werden.
Die Spalte, wo Innen- und Außenhelligkeit gleich sind, gibt an, um welchen Parameter eine Gamma-Korrektur erforderlich ist.
Textur-Filterung wird jedoch für linearen Inhalt gerechnet. Wenn man schwarz und weiß in gleichen Teilen hat, und dann zusammenfiltert, sollte ja eigentlich ein Grauwert heraus kommen, der wie 50% grau aussieht. Die Zahl 0,5 als Grauwert sieht in der Regel aber dunkler aus, als "Mittelgrau" wirken sollte.
Das wäre eigentlich nicht schlimm, da man dies mit Gammakorrektur in den Griff bekommt. Allerdings werden Texturen nicht für solch hohen Gammawerte entwickelt, die man bräuchte, um ein lineares Filterergebnis zu haben. Das Filterergebnis sähe zwar richtig aus, aber zu dem Preis, dass das gesamte Bild viel zu hell wirkt. Zweites Problem: Gammakorrektur mit einem Parameter > 1,0 zieht ja den dunklen Bereich "nach oben", ins hellere. Dunkle Bereiche werden durch kleine Zahlen repräsentiert, und kleine Zahlen haben im Fixpoint-Format einen großen relativen Fehler. Dieser Fehler kann durch gängige Gamma-Parameter (meist wird ein Wert zwischen 1,7 und 2,5 eingestellt) durchaus in den sichtbaren Bereich gelangen.
Einige DirectX9-fähige Grafikkarten können auch für Gamma 2,2 korrekt filtern. Normale Grafikkarten könnten insofern bedient werden, dass die Texturen für einen bestimmten Gamma-Wert vorbereitet werden und das fertige Ergebnis zurückkorrigiert wird. Würde man nun mit Fixpoint-Formaten arbeiten, halst man sich damit die bekannten Genauigkeits-Probleme bei kleinen Zahlenwerten auf. Wir wollen die Erörterung nicht bin ins kleinste Detail ausführen, denn inwiefern die Gamma-Problematik bei Texturfilterung zum Beispiel Einfluss auf die scheinbare Helligkeit von MIP-Maps nimmt, werden wir in einem zukünftigen Artikel noch zeigen.
Im Hinterkopf sollte schon einmal bleiben, dass vernünftige Gamma-korrekte Filterung ohne Floating-Point-Zahlen kaum zu machen ist. Das heißt natürlich auch, dass das FP-Format grundsätzlich sinnvoll ist, wenn man Farben verrechnet. Anstatt auf immer breitere Fixpoint-Darstellungen zu setzen, lohnt es sich, stattdessen aufwändige FP-Logik in den Chip zu integrieren. Die Frage ist nur, ob es unbedingt FP32 sein muss, unserer Meinung nach würde für Farben FP16 die nächsten Jahre ausreichen.
Das gute bei FP-Filterung ist, dass nichtlinearer Content praktisch ohne Genauigkeitsverlust linearisiert werden kann. Anschließend kann linear gerechnet werden und "alles ist in Butter". Diese Verkrampfungen mit "gamma-korrigiertem Filtering" erübrigen sich dann. Filtert man für Gamma 2,2 Texturen oder Polygonkanten "korrekt", heißt das nicht, dass das Endergebnis wirklich korrekt ist. Man verschiebt damit den Fehler aber in andere Bereiche, so dass das Bild meistens besser aussieht.
Unser zweites Beispiel für die Nützlichkeit von FP-Formaten ist unter dem Begriff "High Dynamic Range" ("HDR") vielleicht schon bekannt. Der Monitor kann ja nur Helligkeiten von 0 bis 100% wiedergeben. Scheinbar reicht es doch, den Wertebereich für Farb-Helligkeiten in diesen Grenzen zu halten, denn Größen über 100% müssen vor dem Schreiben in den Framebuffer ja ohnehin auf 100% abgeschnitten werden. Ältere Grafikkarten, die so verfahren, können allerdings solche Bilder nicht rendern:
Ein Screenshot der Demo "Real-Time HDR Image-based Lighting".
Der Glow-Effekt kommt einfach gesagt dadurch zustande, dass "überhelle" Bereiche ihre Umgebung mit erhellen. Dürften die "überhellen" Bereiche maximal 100% Helligkeit aufweisen, wäre der Glow-Effekt schwächer. Man könnte sich auch ein Beispiel vorstellen, in dem eine Lichtreflektion "überhell" wird, man diese allerdings durch eine getönte Scheibe betrachtet, welche das Bild abdunkelt. Bei 200% Helligkeit und 50% Abdunklung blieben 100% Helligkeit übrig. Erlaubt die Grafikkarte kein Overbright Lighting, würde 200% Helligkeit sofort auf 100% abgeschnitten, so dass nach der Abdunklung nur 50% Helligkeit bleiben.
Einen Wertebereich, der über 100% hinaus geht, bietet zwar schon FX12. Aber mit allen Unzulänglichkeiten, die das Fixpoint-Format hat. Wenn Zwischenergebnisse große Zahlen ergeben, macht FP prinzipiell Sinn, denn um so große Zahlen mit einem Fixpoint-Format zu ermöglichen, müsste dieses sehr breit sein. Das Fließkomma-Format hat seine Vorteile aber auch bei sehr kleinen Zwischenergebnissen: Multipliziert man einen Wert mit einer kleinen Zahl, büßt die Fixpoint-Zahl gewaltig an Genauigkeit ein. Floating-Point-Zahlen hingegen behalten fast die gesamte Präzision.
Um bei der Addition und Subtraktion mindestens gleich genau zu sein, wie Fixpoint-Zahlen, darf die Mantisse einer FP-Zahl höchstens ein Bit kürzer sein, als die Fixpoint-Zahl in ihrer Gesamtheit an Bits beansprucht. Aber man braucht beim FP-Format ja auch noch Bits für den Exponenten, und FP-Rechenwerke sind sehr komplex. Trotzdem lohnt sich das eher, als einfach breitere Fixpoints zu nehmen — um zum Beispiel FP16 in jeder Hinsicht das Wasser zu reichen, müsste man schon mit FX41 rechnen (welches dann natürlich an anderen Stellen wieder Vorteile hätte).