Beim Reduzieren der Farbtiefe und beim Dithering mit einem 2-Bit-Rauschen (mit n =] 0,5,1,5 [und Ausgabe = Etage (Eingabe * (2 ^ Bit-1) + n)) werden die Enden des Wertebereichs (Eingaben 0,0 und 1,0) angezeigt ) sind laut. Es wäre wünschenswert, wenn sie einfarbig wären.
Beispiel: https://www.shadertoy.com/view/llsfz4
(oben wird der shadertoy Screenshot eines Gradienten und beide Enden , die darstellend sollten jeweils festen , weißen und schwarzen sein, sind aber laut statt)
Das Problem kann natürlich gelöst werden, indem nur der Wertebereich komprimiert wird, sodass die Enden immer auf einzelne Werte gerundet werden. Das fühlt sich allerdings etwas hackig an und ich frage mich, ob es eine Möglichkeit gibt, dies "richtig" umzusetzen?
image-processing
noise
hotmultimedia
quelle
quelle
Antworten:
TL; DR: 2 * 1LSB-Dreieck-PDF-Dithering bricht in Randfällen bei 0 und 1 aufgrund von Klemmung. Eine Lösung besteht darin, in diesen Randfällen ein einheitliches 1-Bit-Dithering durchzuführen.
Ich füge eine zweite Antwort hinzu, da dies etwas komplizierter ausfiel, als ich ursprünglich gedacht hatte. Es scheint, dass dieses Problem ein "TODO: muss geklemmt werden?" in meinem Code seit ich von normalisiertem zu dreieckigem Dithering gewechselt bin ... im Jahr 2012. Es fühlt sich gut an, es endlich anzusehen :) Vollständiger Code für die im Beitrag verwendeten Lösungen / Bilder: https://www.shadertoy.com/view/llXfzS
Hier ist zunächst das Problem, das wir bei der Quantisierung eines Signals auf 3 Bit mit 2 * 1LSB-Dreieck-PDF-Dithering betrachten:
- im Wesentlichen, was hotmultimedia zeigte.
Mit zunehmendem Kontrast wird der in der Frage beschriebene Effekt deutlich: Die Ausgabe wird in den Randfällen nicht auf Schwarz / Weiß gemittelt (und reicht tatsächlich weit über 0/1 hinaus, bevor Sie dies tun).
Das Betrachten eines Diagramms bietet etwas mehr Einblick:
(graue Linien markieren 0/1, auch in grau ist das Signal, das wir ausgeben möchten, gelbe Linie ist der Durchschnitt der geditherten / quantisierten Ausgabe, rot ist der Fehler (Signalmittelwert)).
Interessanterweise ist die durchschnittliche Ausgabe nicht nur nicht 0/1 an den Grenzen, sondern auch nicht linear (wahrscheinlich aufgrund des dreieckigen PDF des Rauschens). Wenn man das untere Ende betrachtet, ist es intuitiv sinnvoll, warum der Ausgang divergiert: Wenn das Dither-Signal negative Werte enthält, ändert der Clamp-On-Ausgang den Wert der unteren Dither-Teile des Ausgangs (dh der negativen Werte) Erhöhung des Durchschnittswertes. Eine Abbildung scheint in Ordnung zu sein (einheitliches, symmetrisches 2LSB-Dithering, Durchschnitt immer noch in Gelb):
Wenn wir nur ein normalisiertes 1LSB-Dithering verwenden, gibt es überhaupt keine Probleme an den Kantenfällen, aber dann verlieren wir natürlich die schönen Eigenschaften des dreieckigen Ditherings (siehe z . B. diese Präsentation ).
Eine (pragmatische, empirische) Lösung (Hack) besteht dann darin, auf [-0,5; 0,5 [gleichmäßiges Dithering für den Randfall zurückzugreifen:
Dadurch werden die Randfälle repariert, während das dreieckige Dithering für den verbleibenden Bereich erhalten bleibt:
Um Ihre Frage nicht zu beantworten: Ich weiß nicht, ob es eine mathematisch fundiertere Lösung gibt, und ich bin ebenso gespannt darauf, was Masters of Past getan hat :) Bis dahin haben wir zumindest diesen schrecklichen Hack, um unseren Code funktionsfähig zu halten.
BEARBEITEN
Ich sollte wahrscheinlich den in der Frage gegebenen Problemumgehungsvorschlag zum einfachen Komprimieren des Signals behandeln. Da der Durchschnitt in den Randfällen nicht linear ist, führt das einfache Komprimieren des Eingangssignals nicht zu einem perfekten Ergebnis - obwohl die Endpunkte festgelegt werden:
Verweise
quelle
dithertri
unddithernorm
anstelle eines unabhängigen wieder verwendet. Sobald Sie alle Berechnungen durchgearbeitet und alle Begriffe abgebrochen haben, werden Sie feststellen, dass Sie überhaupt nicht lerping! Stattdessen wirkt der Code wie ein harter Cutoff undv < 0.5 / depth || v > 1 - 0.5/depth
wechselt sofort zur dortigen Gleichverteilung. Nicht, dass es Ihnen das schöne Zittern nimmt, es ist nur unnötig kompliziert. Das Beheben des Fehlers ist tatsächlich schlecht, Sie werden mit einem schlimmeren Zittern enden. Verwenden Sie einfach einen harten Cutoff.Ich bin nicht sicher, ob ich Ihre Frage vollständig beantworten kann, aber ich werde einige Gedanken hinzufügen und vielleicht können wir gemeinsam eine Antwort finden :)
Erstens ist mir die Grundlage der Frage etwas unklar: Warum halten Sie es für wünschenswert, sauberes Schwarz / Weiß zu haben, wenn jede andere Farbe Rauschen aufweist? Das ideale Ergebnis nach dem Dithering ist Ihr ursprüngliches Signal mit völlig gleichmäßigem Rauschen. Wenn Schwarz und Weiß unterschiedlich sind, wird Ihr Rauschen signalabhängig (was jedoch in Ordnung sein kann, da es ohnehin dort auftritt, wo Farben geklemmt werden).
Es gibt jedoch Situationen, in denen Rauschen in Weiß oder Schwarz ein Problem darstellt (mir sind keine Anwendungsfälle bekannt, bei denen sowohl Schwarz als auch Weiß gleichzeitig "sauber" sein müssen): Beim Rendern eines additiv gemischten Partikels als Quad mit Bei einer Textur möchten Sie nicht, dass im gesamten Quad Rauschen hinzugefügt wird, da dies auch außerhalb der Textur angezeigt wird. Eine Lösung besteht darin, das Rauschen zu kompensieren, anstatt [-0,5; 1,5 [[-2,0; 0,0 [(dh 2 Bit Rauschen subtrahieren)) zu addieren. Dies ist eine ziemlich empirische Lösung, aber mir ist kein korrekterer Ansatz bekannt. Wenn Sie darüber nachdenken, möchten Sie wahrscheinlich auch Ihr Signal verstärken, um die verlorene Intensität auszugleichen ...
Etwas verwandt hielt Timothy Lottes einen GDC-Vortrag über die Formung von Rauschen in den Teilen des Spektrums, in denen es am dringendsten benötigt wird, und reduzierte das Rauschen am hellen Ende des Spektrums: http://32ipi028l5q82yhj72224m8j-wpengine.netdna-ssl.com/wp- content / uploads / 2016/03 / GdcVdrLottes.pdf
quelle
Ich habe Mikkel Gjoels Idee, mit dreieckigem Rauschen zu zittern, zu einer einfachen Funktion vereinfacht, die nur einen einzigen RNG-Aufruf benötigt. Ich habe alle unnötigen Teile entfernt, damit es ziemlich lesbar und verständlich sein sollte, was los ist:
Für die Idee und den Kontext verweise ich Sie auf die Antwort von Mikkel Gjoel.
quelle
Ich folgte den Links zu dieser ausgezeichneten Frage zusammen mit dem Shadertoy-Beispiel.
Ich habe einige Fragen zur vorgeschlagenen Lösung:
Gute Arbeit! Ich möchte sehen, dass ich Ihren Gedankengang richtig verstanden habe. Vielen Dank!
quelle