Schrompf hat geschrieben:Wenn das die Zukunft der Grafikprogrammierung ist, wechsel ich zur Gärtnerei.
Keine Angst … wenn man es einmal verstanden hat und – anders als ich – die Beschränkungen im Voraus kennt, ist es relativ einfach.
CodingCat hat geschrieben:Jetzt könntest du btw. nochmal ein schönes Bild mit fertigem Glare und farbigen Sternen posten. ;-)
Da kommt leider noch einiges dazwischen :/ Ein Detail, was noch fehlt, ist z.B., dass ich die Point Spread Function so modifizieren muss, dass sie für den mittleren Pixel einen gedämpften Wert zurückgibt. Der Grund dafür ist, dass ich für die FFT das Anti-Aliasing des Bildes auflösen musste und das Streubild zusätzlich noch verwaschen ist (allein, weil man in einer PSF mit gerader Seitenlänge keinen scharfen Mittelpunkt erzeugen kann, liegt ein 2×2-Blur über dem Bild). Ich muss also noch die PSF bearbeiten und mit dem geantialiasten Originalbild kombinieren … das habe ich bisher überhaupt noch nicht angepackt. (Und habe jetzt auch erstmal akutere Probleme zu lösen :/)
Eisflamme hat geschrieben:Also ich verstehe noch nicht so ganz, was du jetzt eigentlich bastelst. Anscheinend hast Du als Ausgangsbild eine Szene, aber wie ist die dargestellt? Ich meine, bedeutet ein heller Pixel jetzt, dass von da aus Licht kommt und, indem du schaust, wie die optische Physik zwischen Auge und im Auge arbeitet, baust Du die Streuung des Lichts ein, wie sie wahrgenommen wird?
Ich habe ein Ausgangsbild der Szene, wo für jeden Pixel seine Helligkeit in cd÷m² eingetragen ist – ein weitestgehend normaler HDR-Backbuffer.
Nun haue ich da einen Blur drüber. Normalerweise berechnet man diesen Blur anhand einer Gauss-Formel, während man die umliegenden Pixel abtastet … ich lade die Koeffizienten hingegen aus einer Textur.
In dieser Textur ist abgebildet, wie ein einziger Pixel, der durchs Auge fällt, sein Licht streut (also der Strahlenkranz eines einzelnen Pixels – siehe Bild 5, nur, dass dort der Koordinatenursprung in der Ecke statt am Rand ist). Das ist sozusagen mein Blur-Kernel, und ich habe ihn durch die Innenansicht des Auges (Bild 3) und Fresnel’sche Beugungsformeln (Bild 4) berechnet.
Ich wende also den Strahlenkranz-Blur auf jeden Pixel der Szene an … da das hier ein HDR-Bild ist und so ein Stern (wie in Wirklichkeit) tausendmal heller ist als die Umgebung drumherum, kommt sein Strahlenkranz deutlich zum Vorschein während jener der dunklen Universumspixel unbemerkt untergeht.
Die Fourier-Transformation dient dazu, diesen Effekt erheblich zu beschleunigen – ein Blur mit einem Radius von mehreren hundert Pixeln ist nämlich saulangsam. Wenn man hingegen von zwei Bildern die Fourier-Transformation berechnet (Bild 2 & 6), die beiden miteinander multipliziert (Bild 7) und dann die inverse Fourier-Transformation berechnet, ist es, als ob das komplette Bild B auf jeden Pixel des Bildes A draufprojeziert wurde.
Ich hoffe, das war einigermaßen anschaulich beschrieben.
Eisflamme hat geschrieben:Wenn das in Echtzeit funktionieren würde, wäre das also eine realistischere Art der Belichtung in Szenen, wobei man als Ausgangsmaterial einfach nur ein paar einfache Parameter wie Position, Stärke etc. des Lichts angeben müsste?
Erst einmal
funktioniert es bereits in Echtzeit, nur habe ich (noch) keinen Prototypen mit mehr als 512×512 Pixeln Auflösung ;) Du musst für das Licht
garnichts angeben. Der normale Frame, den man rendert,
ist ja bereits nichts anderes als eine große Liste von Helligkeiten, die aus verschiedenen Richtungen kommen. Der Algorithmus ist immer gleich schnell (oder langsam), egal, ob da nur ein einziger beleuchteter Pixel in der Szene ist, tausend (wie bei einem Sternenhimmel) oder millionen (wenn der Spieler virtuell per Fernglas in die Sonne guckt).