Gesammelte Synapsenkurzschlüsse

Kommentare anzeigen Worklog abonnieren
Gehe zu Seite Zurück  1, 2

Worklogs Gesammelte Synapsenkurzschlüsse

Noch besseres Voxelrendering

Dienstag, 23. März 2010 von Noobody
Das Rauschen konnte ich nun endlich entfernen und habe ausserdem den Shader um einiges schneller gemacht. Das Programm fängt jetzt ausserdem jedwede Inkompatibilitäten mit der Grafikkarte ab, um möglichst überall zu funktionieren.

Damit ich nicht dasselbe zweimal schreiben muss, verweise ich jetzt einfach mal auf den Eintrag im WiP: Beitrag mit Demo

Besseres Voxelrendering

Donnerstag, 18. März 2010 von Noobody
Heute fügte ich noch schnell eine prozedurale Perlin-Noise Textur, eine bessere Normalen- und Schnittpunktsinterpolation, Phong shading und Schatten hinzu. Mal abgesehen vom schwarz-grauen Rauschen aufgrund nicht berechenbarer Normalen bin ich ziemlich zufrieden Razz
user posted image

Immer noch Echtzeit!

Voxelraycasting auf der GPU

Dienstag, 16. März 2010 von Noobody
Durch einem Thread im englischen Forum angeregt (jemand bastelte einen Voxelrenderer in BMax) schrieb ich mir einen Shader für Voxelraycasting. Damit renderte ich heute gleich das berühmte Stanford Terracottahäschen:
user posted image
Das Modell hat leider ein paar Fehler, die ich wohl noch ausbügeln muss, und die Farbgebung ist auch ein wenig phantasielos, aber das wird schon. Das Modell ist 512x512x512 Voxel gross (=128MB, 1 Byte pro Voxel). Die ursprünglichen 12 Bit des Modells stauchte ich ein wenig zusammen, um den Grafikspeicher zu schonen. Das eine Byte bezeichnet übrigens die Elektronendichte, die bei der Aufnahme im Computertomographen gemessen wurde. Der Raycaster filtert dann die Voxel mit der richtigen Dichte raus, um nur das Häschen anzuzeigen.

Das ganze läuft bei 1024x768 in Echtzeit auf einer HD4890.

Kleines Update

Freitag, 26. Februar 2010 von Noobody
Ich fügte heute Color Bleeding zum Photon Mapping hinzu, welches mir so gefiel, dass ich hier den aktuellen Render poste Razz
user posted image
Das Licht ist knapp unter der Decke und strahlt auf die Szene herab. Die Decke selbst wird nur von indirekter Beleuchtung erhellt, sprich vom Licht, dass von den Wänden abprallt und irgendwann die Decke trifft. Die rote und die grüne Wand jeweils strahlen die umgebenden Wände in der entsprechenden Farbe an (die Farbe läuft quasi aus der Wand raus in die Umgebung => Color Bleeding). Besonders gefällt mir der kleine grüne Fleck vorne an der linken Wand, der von der Bündelung des grünen abgestrahlten Lichts der rechten Wand durch die Glaskugel stammt. Der schwache rote Ring um die Kaustik unter der Kugel ist auch ganz hübsch; er kommt von abgelenkten roten Photonen, die von der linken Wand abprallen und durch die Glaskugel gebrochen werden.

Noch zum Vergleich, die gleiche Szene ohne Photon Mapping:
user posted image
Die Decke ist komplett schwarz, da keine indirekte Beleuchtung stattfindet, die Kaustik fehlt und von Color Bleeding ist auch nichts zu sehen.

Neue alte Projekte

Donnerstag, 25. Februar 2010 von Noobody
Ich breche mal das betretene Schweigen hier und melde mich wieder mit neuen alten Projekten. In letzter Zeit verbrachte ich viel Zeit mit meinem BCC-Beitrag Chaos Hack und dem Perlin-Noise-Generator, der seit einiger Zeit hier auf der Festplatte herumlag (ich erwähnte ihn sogar im ersten Worklog-Eintrag, wie ich gerade feststelle Razz ). Ich machte den Generator nicht realtime-fähig, aber immerhin ansehnlicher als die öde Heightmap, indem ich GLSL zu Hilfe nahm und einen entsprechenden Perlin-Noise-Raytracer-Shader schrieb.

Dieser funktioniert auf Basis des Raymarching - sprich, man berechnet nicht wirklich den mathematisch genauen Schnittpunkt des Sichtstrahls mit der Perlin-Noise-Funktion, sondern man nimmt einen viel simpleren Ansatz: Man geht einfach Schrittweise auf dem Strahl entlang, bis entweder der Y-Wert der aktuellen Position unter dem Terrain liegt oder man so weit von der Kamera entfernt ist, dass ziemlich sicher kein Schnittpunkt mehr kommt und stattdessen der Himmel eingezeichnet wird. Das Bild wird dann natürlich umso schöner, je kleiner die Schrittweite auf dem Strahl ist; allerdings dauert dann das Rendern länger.

Eine kleine Optimierung holt jedoch nochmal ordentlich Geschwindigkeit heraus: Da man die Details sowieso immer schlechter erkennen kann, je weiter das Terrain entfernt ist, erhöht man die Schrittweite einfach abhängig von der bereits zurückgelegten Entfernung. Am Anfang startet man beispielsweise mit einer Schrittweite von 0.001, um auch die ganz kleinen Details einfangen zu können, erhöht aber die Schrittweite jedesmal, so dass man am Ende mit 0.1 Einheiten grossen Schritten unterwegs ist.

Wenn man zu den Terrainfarben noch ein kleines bisschen Nebel, abhängig von der Entfernung, hinzumischt, sieht das natürlich viel netter aus. Fügt man dann noch eine blaue Himmelsfarbe mit interpoliertem Perlin Noise für Wolken hinzu, plus ein Weissanteil abhängig von der Entfernung, um den Horizont zu simulieren, erhält man so etwas hier. Ja, es ist genau dasselbe Bild, wie ich in der Galerie hochgeladen habe - mir gefällt die Stelle einfach Razz Ich suchte noch ein paar Mal nach hübscheren Stellen (da das Terrain theoretisch unendlich gross ist, gibt es ja auch unendlich viele hübsche Stellen), aber gab es irgendwann auf.

Um zu etwas anderem zu kommen, vor ein paar Tagen grub ich wieder das Buch 'Realistic image synthesis using photon mapping' aus und machte mich an eine Implementation des Algorithmus'... Algorithmuses? Algorithmuss? Ach, einfach Photon Mapping. Photon Mapping ist eine Methode, globale Beleuchtung zu simulieren. Was ist globale Beleuchtung? Nun, bisher unterstützte mein Raytracer nur direkte Beleuchtung. Das heisst, ich schickte Strahlen von der Kamera aus in die Szene (je nach dem wurden die Strahlen auch noch gebrochen oder reflektiert), ermittelte die Beleuchtung an den Schnittstellen durch eine Funktion, die die Oberflächennormale und den Vektor zum Licht nimmt und einen Beleuchtungswert ausspuckt und malte den passenden Pixel auf dem Bildschirm entsprechend an. Das funktioniert schön und gut, aber wenn es darum geht, tolles Zeug wie Color Bleeding oder Kaustiken zu simulieren, ist die Methode einfach nutzlos, da man nicht einfangen kann, dass Licht von allen Oberflächen reflektiert wird und nicht nur Spiegeln.

Hier kommt Photon Mapping ins Spiel: Bevor man das eigentliche Bild rendert, schickt man virtuelle Photonen von den Lichtquellen in die Szene, simuliert, wie sie von den Oberflächen abprallen und je nach Material an Kraft und Farbe verlieren. Jedesmal, wenn ein Photon eine diffuse Oberfläche trifft, wird es an der Position gespeichert. Später, in der eigentlichen Renderphase, werden zusätzlich zur direkten Beleuchtung die x nächsten gepspeicherten Photonen hinzugezogen und aus ihnen dann die finale Beleuchtung berechnet. Die dazu benötigten Integrale im Buch sind 'mindbending', wie die Engländer so schön sagen, und ich habe auch noch längst nicht alles verstanden geschweige denn eingebaut, aber eine grundlegene Implementation ist fertig und läuft:
user posted image
Das tolle ist, dass man mit Photon Mapping auch noch Ambient Occlusion und Soft Shadows gratis dazubekommt - ziemlich praktisch.

Damit ich mal mit Zahlenwerten um mich werfen kann: Insgesamt werden 5'000'000 Photonen verwendet und beim Rendern 2'000'000 Lichtstrahlen in die Szene geschickt. Pro Lichtstrahl werden die 25'000 nächsten Photonen hinzugezogen, was schlussendlich 50 Billionen Photonenaufrufe bedeutet. Ich war selber ein wenig von den Ausmassen überrascht, aber dank dem kD-Tree, in dem die Photonen gespeichert sind, wird das ganze in einer mehr oder weniger flotten halben Stunde gerendert (1600x1200 Pixel, wegen Antialiasing).

In nächster Zeit werde ich wohl weiterhin am Raytracer sitzen. Color Bleeding funktioniert noch nicht, als BRDF werden bisher nur diffuse Oberflächen unterstützt, die Materialklasse könnte mal eine Auffrischung vertragen und für Objekte muss ich auch unbedingt mal einen kD-Tree einbauen (für die Photonen verwende ich notwendigerweise bereits einen, aber der für die Photonen war auch viel einfacher zu schreiben). Bisher verwendete ich für die Dreiecke der Metaballs ein Gitter und für den Rest eine einfache Liste, aber das ist einfach zu langsam. Sobald der Raytracer wieder auf Vordermann gebracht ist, kann ich endlich ein noch tolleres Wasservideo rendern Razz

Mehr Unsinn

Sonntag, 17. Januar 2010 von Noobody
Nach einer Woche in England bei meiner Schwester und ihrem Freund mit köstlichem Guinness, Cider und Diablo II (zu dritt äusserst spassig) gibt es auch wieder neues zu berichten.

An der 2D-SPH Simulation arbeitete ich weiter und konnte einige kleinere Unstimmigkeiten beheben. Mittlerweile bin ich wieder so weit, dass ich Hindernisse fertig re-implementiert und Soft Bodies sowie erste Anfänge eines partikelbasierten Rigid Body Systems geschrieben habe. Soft Bodies interagieren nun endlich auch mit allen Flüssigkeiten sowie Soft Bodies aus anderen Materialien, obwohl Flüssigkeiten gerne mal zwischen die Soft Body Partikel geraten und unschön rumzuckeln.
Ausserdem habe ich mich über Oberflächenspannung informiert und eine fertige Implementation geschrieben. Durch die Oberflächenspannung kann verhindert werden, dass sich in Simulationen mit mehreren Flüssigkeiten einzelne Partikel aus dem Flüssigkeitsverband lösen und in die andere Flüssigkeit übertreten (ist auch im Video sichtbar).

Um all das zu demonstrieren, habe ich eine kleine Demo zusammengeschnürt:
user posted image
Download (Exe + BMax Code): Link

Mit den Tasten 1 - 3 kann man die Beispiele wechseln, in jedem Beispiel bewirkt meistens Leertaste/Linke/Rechte Maustaste etwas, einfach ausprobieren. Rigid Bodies sind noch sehr experimentell, Kollision untereinander ist überhaupt nicht eingebaut und bei der Kollision mit dem Boden hab ich Probleme mit der Energieerhaltung. Kleinere Objekte versinken, grössere schweben in der Luft. Mal sehen, ob ich das noch hinkriege Razz

Desweiteren habe ich am Raytracer weitergearbeitet. Das Problem, das ich über die letzten Monate mit den selbergebastelten TransformPoint/Vector/Normalbefehlen hatte, konnte ich in England nun endlich erledigen, was einige Bild- und Berechnungsfehler behoben hat.
Ausserdem plane ich, ein kleines Stadtmodell im Raytracer mit einem Tsunami zu fluten und davon ein Video online zu stellen. Dafür holte ich mir aus dem Google 3D Warehouse ein Modell einer Stadt auf einer Insel, für das 2012 ein wenig früher kommen wird:
user posted image
user posted image
Da das Modell im .obj-Format vorliegt, habe ich mir einen OBJ-Loader in B3D geschrieben, der für meine Zwecke wohl genügen wird. Den muss ich dann nur noch nach C++ portieren, damit der Raytracer endlich Modelle laden kann!

Ansonsten habe ich nicht viel getan. Mit dem Buch über Photon Mapping bin ich nun fast fertig, mal sehen, wann ich dazu komme, das Gelernte in den Raytracer einzubauen. Da ich mir vor kurzem einen neuen Computer gekauft habe, komme ich leider nich viel zum Programmieren - es gibt so viele tolle Spiele da draussen, die ich bisher nicht spielen konnte, daher herrscht einiges an Nachholbedarf Razz Ausserdem kann ich nun endlich die neusten 3D-Techniken ausprobieren und nachcoden, da die notwendige Hardware bei mir vorhanden ist. Ein per Shader berechnetes SPH wäre natürlich sehr geil, aber das steht noch in den Sternen, ob ich sowas hinbekomme.

Gesammelter Unsinn

Samstag, 26. Dezember 2009 von Noobody
Worum gehts hier überhaupt?

Nun, in diesem Worklog soll es darum gehen, meine kleineren und grösseren Projekte unter ein Dach zu bekommen. Bisher postete ich die 'fertigeren' meistens im Codearchiv oder im WiP, allerdings fand ich es immer schwierig, zu entscheiden, was wohin gehört (und ob ich es überhaupt posten sollte). Viel lieber wäre es mir jedoch gewesen, wenn ich den Fortschritt einzelner Programme hätte dokumentieren können. Ein Worklog pro Codefetzen wäre aber definitiv viel zu viel und würde auch von den Moderatoren kaum gerne gesehen. Daher werde ich nun einfach diesen Worklog dazu verwenden, gelegentlich einen Eintrag zu schreiben, um kleinere Projekte zu veröffentlichen und bei längeren Projekten den aktuellen Stand festzuhalten.

Selbstverständlich darf man bei den kleineren Codes nicht viel sinnvolles erwarten. Da ich einen Flair für mathematische Phänomene habe, werden wohl auch viele Programme dabei sein, die einfach nur interessante Bilder produzieren, für Spiele oder Anwendungen aber komplett nutzlos sind. Gelegentlich wird aber sicher für den einen oder anderen etwas brauchbares dabei sein Wink


Im Moment arbeite ich gerade wieder an meiner Wassersimulation mithilfe von SPH weiter, die ich schon ein paar mal im Forum postete. Ich strukturiere momentan den Code nochmals neu, um mehrere Materialien gleichzeitig simulieren zu können. Heute baute ich die Berechnungen für Flüssigkeiten wieder ein und nahm ein Video davon auf: Youtube-Link. Screenshot:
user posted image
Die rote Flüssigkeit besitzt ca. die dreifache Dichte von Wasser, die Grüne etwa die halbe Dichte von Wasser, während die Dichte der blauen Flüssigkeit ungefähr der von Wasser entspricht.

Die Simulation läuft noch nicht so, wie ich mir das vorstelle. Ich habe immer noch Probleme, die Dichteverteilung richtig zu berechnen, ohne dass die ganze Simulation in die Luft fliegt. Ausserdem habe ich noch keine Oberflächenspannung eingebaut, was in nächster Zeit noch implementiert wird.
Ansonsten komme ich bisher relativ gut mit dem Code voran. Morgen werde ich vorraussichtlich die Hindernisse und die Soft Bodies fertig einbauen, um sie mit dem Wasser interagieren zu lassen. Den Code schreibe ich im Moment mit einem zukünftigen Modul im Hinterkopf, damit ich mir nicht selber Steine in den Weg lege, falls ich ernsthaft daran weiterarbeiten will.

Die 3D-Variante ist für den Moment auf Eis gelegt. Auf Weihnachten bekam ich das wunderbare Buch von Henrik Jensen geschenkt, was bedeutet, dass ich als nächstes wohl Photon Mapping in den Raytracer einbaue. Photon Mapping erlaubt sehr viel schönere Beleuchtung und Kaustiken (Bündelungen des Lichts durch Objekte wie etwa Glas oder Wasser), was den Realismus der Bilder um einiges steigert. Allerdings ist die Theorie dahinter nicht ganz ohne, weswegen ich das auf meiner Prioritätenliste ein wenig weiter nach unten schiebe.


Aus reinem Interesse implementierte ich vor einer Woche ausserdem einen Perlin Noise-Generator in BMax, um prozedural Heightmaps generieren zu können. Dieser liefert relativ hübsche Ergebnisse, wenn auch nicht besonders schnell:
user posted image
Da ich am selben Abend gleich eine zündende Idee hatte (Synapsenkurzschluss Razz ), probierte ich mich an einem Erosionsfilter für Heightmaps. Dieser simuliert natürliche Erosion durch Regen und andere Witterung, um schönere Terrains zu erhalten (links das Original):
user posted imageuser posted image
Die Ergebnisse sind wie immer noch nicht perfekt. Die Einschnitte ins Terrain sind ein wenig zu tief, weswegen das gerenderte Terrain nicht ganz so schön aussieht, aber für den Moment bin ich mit den Resultaten zufrieden.

Ich hatte die Idee, den Perlin Noise-Generator mit dem Erosionsfilter und dem Lightmapper zu kombinieren, den ich mal ins Codearchiv stellte, um eine Kamerafahrt durch ein unendlich grosses, sich ständig erweiterndes Terrain zu ermöglichen. Da ich in BMax aber keine Blitzterrains zur Verfügung habe, um die Anzahl gerenderter Dreiecke zu drücken, baute ich mir eine Geomipmapping-Implementation in BMax, die auch schon funktioniert - rein in der Theorie. Da ich mich aber noch nie mit dem effizientem Rendern von Meshes in OGL beschäftigt habe, kann ich die erzeugte Dreiecksliste noch nicht darstellen. Falls ich in nächster Zeit dazu komme, bastle ich daran weiter.

So, das wäre es für den ersten Eintrag. Bei Fragen oder Anregungen schreibt nur Kommentare oder eine PN an mich.

Guten Rutsch Razz

Gehe zu Seite Zurück  1, 2