Trace It! - Raytracing mit BB

Kommentare anzeigen Worklog abonnieren

Worklogs Trace It! - Raytracing mit BB

Polygone, Polgyone und Polygone!

Dienstag, 2. Juni 2009 von Darren
guten tag allerseits,

ein weiterer meilenstein wurde von mir in den boden gehauen. mittlerweile kann ich auch schnittpunkte mit dreiecken berechnen. heißt im klartext: jetzt gehts rund! Naja ganz so schlimm ist es nicht aber zumindest lassen sich jetzt schonmal schönere und interessantere bilder erstellen.

Die Polygone werden in einer seperaten Datei gespeichert. wieder xml. scheint mir das komfortabelste zu sein. Es werden erst einmal nur eckpunkte gespeichert. die normale wird beim laden berechnet und uv-koordinaten brauchts bis jetzt noch nicht.

im shading wurde jetzt einiges optimiert. jetzt wird an jedem pixel für jeden material-kanal erst einmal die farbe ohne lighting berechnet, indem in einer getrennten funktion shader und schnittpunkt zur kanal-farbe verarbeitet werden.

ansonsten hab ich nochn bisschen aufgeräumt und bisschen getweaked, wo ich was gefunden habe.

so long

hier nochn neuer screenshot:
http://dl.getdropbox.com/u/416097/test10088630.bmp (900 KB)

~Editiert~
Keine BMPs direkt anzeigen lassen! Eigentlich: Gar keine BMPs im Internet benutzen. MfG D2006

Matrizen, Specular...

Donnerstag, 28. Mai 2009 von Darren
Hallo zusammen!

Bevor ich mich den technischen Details widmen werde, möchte ich alle Interessierten mal auf meine Facharbeit hinweisen, die ich im Rahmen vom Mathe-Leistungskurs verfasst habe. Gab volle Punktzahl drauf. Zwar hatte der Lehrer keine Ahnung vom Thema selbst, doch scheinbar hat ihn die Art des Erklärens gefallen. Hier mal ein Link für alle interessierten:

http://dl.getdropbox.com/u/416097/fa_final.pdf

Bis jetzt ist mein Programm bis auf das Vorhandensein von getracten Schatten eine praktische Umsetzung meiner Facharbeit. Wer also mal Lust hat in den code zu schauen, wird sich besser zurechtfinden, wenn er sich die Arbeit mal zu Gemüte führt.

Matrizen in der Schnittpunktberechnung haben mich viel Zeit und Nerven gekostet, weil ich nur wusste, _dass_ ein korrektes Tracen des Strahles nur funktioniert, wenn ich ihn in die lokalen Objektkoordinaten transformiere, dort die Berechnungen anstelle und wieder zurück transformiere. Jedoch hatte ich noch keinen wirklichen Plan, _wie_ so eine Transformationsmatrix angewendet geschweige denn berechnet wird. Also musste ich mich erst einmal ein bisschen in die Materie einarbeiten. (traurig, dass ich in bayern abitur gemacht habe, matheLK hatte und trotzdem nicht von matrizen weiß -.-*) Mittlerweile wird der Strahl in jedes KOSY richtig transformiert. Jedoch habe ich Rotation noch nicht implementiert. Sollte aber kein weiteres Problem mehr darstellen. Bis jetzt sind diese Transformationen nur interessant, wenn man "Eier" darstellen will. Kugeln können also bereits gestaucht und gestreckt werden, und auch die Normale am Schnittpunkt wird richtig transformiert. Zwar nicht ganz richtig, weil ich bis jetzt noch die inversa matrix verwende und nicht die transponierte Matrix der Inversen, aber das ist auch erst bei Rotationen wichtig.

Gleich danach habe ich den Glanzlichtanteil mit reingehackt. War nicht so schwierig, weil ich das ja schon einmal getan hatte, und nur kurz in meiner Facharbeit für die exakte Formel nachschlagen musste.

Neben dem Color-Shader, gibt es jetzt auch einen Grid-Shader, der in bestimmten Abständen in x-Richtung eine Linie von bestimmter Breite zeichnet. Im Shader werden die beiden Farben, der Abstand der Linien und die breite der Linie gespeichert und beim Shading unter Berücksichtigung der Weltkoordinaten die Farbe im jeweiligen Kanal berechnet. Die Shader sind auch kanalunabhängig. Sie können bis jetzt im Farb- und Glanzlichtkanal verwendet werden.

Als nächstes möchte ich das Kameramodell ein wenig ausbauen. Es soll nicht mehr die Blickrichtung gegeben sein, sondern die Rotation um alle drei Welt-Koordinatenachsen. Macht die ganze Sache ein wenig flexibler und anschaulicher. Außerdem kann ich mich dann gleich mit der Rotation befassen und die dann bei den Objekten mit einbauen.

Außerdem ist das hier die erste Veröffentlichung des bis jetzt bestehenden Quellcodes. Somit kann jetzt jeder der will etwas dazu beitragen. Sei es ein kleiner Bugfix, oder hier und da ein kleines Speedup. Ich würde mich natürlich noch mehr darüber freuen, wenn sich der eine oder andere dazu bereit erklären würde aktiv an dem Projekt mitzuarbeiten. Natürlich könnt ihr durch die GPL-Lizenz auch euer eignes Ding mit dem Code machen. Würde mich auch nicht stören und ich wäre gespannt was dabei herauskommen würde. Wer also Interesse hat, mir in irgendeiner Art zu helfen, kann sich per PN bei mir melden.

Hier ist der Link zum Archiv mit einer Binary, dem Source und einer Sample-Szene(620kb):
http://dl.getdropbox.com/u/416097/traceit.zip

Und für alle die wissen wollen, was das Tool bis jetzt produziert:
user posted image

Vielen Dank für die erbrachte Aufmerksamkeit!

Kompletter rewrite nummer was weiß ich

Montag, 25. Mai 2009 von Darren
guten tag miteinander!

zwar habe ich übermorgen mündliche abiturprüfung und eigentlich sollte ich ein schlechtes gewissen haben, überhaupt ein paar minuten am PC zu verbringen, doch ich konnte einfach nicht widerstehen. ich habe meinen kleinen raytracer noch einmal von grund auf neu geschrieben. diesmal habe ich gleich allgemeiner und modularer begonnen.

es gibt bereits ein eigenes kleines und einfaches "dateiformat". als syntax wird xml benutzt und mit der blitzXML-library ausgelesen. nun shader habe ich auch schon fest mit reingestrickt. bis jetzt gibt es zwar nur einen color/shader, aber der reicht ja auch noch, zumal ich gerade noch mehr an den schnittpunkt-algos rumfurwerkel als am shading. geplant ist ein gridshader, ein verlaufsshader, ein imageshader und ein cel-shader.
hier mal ein kleines beispiel für eine szenen-datei. diese benutzen ich auch die ganze zeit um meine renders zu testen:

Code: [AUSKLAPPEN]
<?xml version="1.0" encoding="UTF-8"?>
<file>
   <scene>
         <width>400</width>
         <height>300</height>
         <cam_x1>0</cam_x1>
         <cam_x2>10</cam_x2>
         <cam_x3>-10</cam_x3>
         <cam_dir_x>0</cam_dir_x>
         <cam_dir_y>-0.4</cam_dir_y>
         <cam_dir_z>1</cam_dir_z>
         <fov>65</fov>
         <amb_r>0.2</amb_r>
         <amb_g>0.2</amb_g>
         <amb_b>0.2</amb_b>
         <output_file>test</output_file>
   </scene>
   <sha>
      <shader>
         <name>shader1</name>
         <typ>0</typ>
         <col_r>0.1</col_r>
         <col_g>0.8</col_g>
         <col_b>0.9</col_b>
      </shader>
      <shader>
         <name>shader2</name>
         <typ>0</typ>
         <col_r>0.9</col_r>
         <col_g>0.5</col_g>
         <col_b>0.3</col_b>
      </shader>
      <shader>
         <name>shader3</name>
         <typ>0</typ>
         <col_r>0.7</col_r>
         <col_g>0.7</col_g>
         <col_b>0.7</col_b>
      </shader>
   </sha>
   <obj>
      <objct name="licht1" type="5">
         <pos_x>7</pos_x>
         <pos_y>72</pos_y>
         <pos_z>-7</pos_z>
         <r>1</r>
         <g>1</g>
         <b>1</b>
         <brightness>1</brightness>
      </objct>
      <objct name="ebene" type="1">
         <n1>0</n1>
         <n2>1</n2>
         <n3>0</n3>
         <n4>0</n4>
         <material>boden</material>
      </objct>
      <objct name="kugel1" type="0">
         <pos_x>0</pos_x>
         <pos_y>2</pos_y>
         <pos_z>0</pos_z>
         <scale_x>1</scale_x>
         <scale_y>2</scale_y>
         <scale_z>1</scale_z>
         <radius>1</radius>
         <material>mat1</material>
      </objct>
      <objct name="kugel2" type="0">
         <pos_x>5</pos_x>
         <pos_y>1</pos_y>
         <pos_z>6</pos_z>
         <scale_x>1</scale_x>
         <scale_y>1</scale_y>
         <scale_z>1</scale_z>
         <radius>1</radius>
         <material>bam</material>
      </objct>               

   </obj>
   <mat>
      <material name="mat1">
         <dif_shader>shader1</dif_shader>
         <exponent>5</exponent>
         <spec_r>0.3</spec_r>
         <spec_g>1</spec_g>
         <spec_b>0.2</spec_b>
         <refl_int>1</refl_int>
         <refl_r>1</refl_r>
         <refl_g>1</refl_g>
         <refl_b>1</refl_b>
      </material>
      <material name="bam">
         <dif_shader>shader2</dif_shader>
         <exponent>25</exponent>
         <spec_r>0.7</spec_r>
         <spec_g>1</spec_g>
         <spec_b>0.6</spec_b>
         <refl_int>0.5</refl_int>
         <refl_r>1</refl_r>
         <refl_g>1</refl_g>
         <refl_b>1</refl_b>
      </material>
      <material name="boden">
         <dif_shader>shader3</dif_shader>
         <exponent>25</exponent>
         <spec_r>0.7</spec_r>
         <spec_g>1</spec_g>
         <spec_b>0.6</spec_b>
         <refl_int>0.5</refl_int>
         <refl_r>1</refl_r>
         <refl_g>1</refl_g>
         <refl_b>1</refl_b>
      </material>
   </mat>
</file>


und hier ist das logfile, das von dem programm beim ausführen erstellt wird. dient begrenzt auch einigen debuggingzwecken, soll aber vor allem dann die ganze sache bissen benutzerfreundlicher machen.

Code: [AUSKLAPPEN]

Found scene-file... processing

 ---

Starting to parse file: scene1.xml

Resolution - Width: 400; Height: 300

Output-File: test.bmp

Camera-Coords: (0.0/10.0/-10.0)

Camera-Direction: 0.0 -0.371391 0.928477

Vertical FOV: 65°

Ambient-light: 0.2 0.2 0.2

 ---

Looking for shaders...

Found 3 shaders... Reading them...

Loaded Colour-Shader 'shader1'.

Loaded Colour-Shader 'shader2'.

Loaded Colour-Shader 'shader3'.

 ---

Looking for materials...

Found 3 materials... Reading them...

Created material 'mat1':

    Color-channel: shader1

   Specular with exponent: 5.0 - 0.3 1.0 0.2

   Reflection with intensity: 1.0 - 1.0 1.0 1.0

Created material 'bam':

    Color-channel: shader2

   Specular with exponent: 25.0 - 0.7 1.0 0.6

   Reflection with intensity: 0.5 - 1.0 1.0 1.0

Created material 'boden':

    Color-channel: shader3

   Specular with exponent: 25.0 - 0.7 1.0 0.6

   Reflection with intensity: 0.5 - 1.0 1.0 1.0

 ---

Looking for objects...

Scene contains 4 objects.

Created light 'licht1:

    Position: (7.0/72.0/-7.0)

    Color: 1.0 1.0 1.0

Created plane 'ebene:

    Normal Vector: 0.0 1.0 0.0

    n4: 0.0

    Material: boden

Created sphere 'kugel1:

    Radius: 1.0

    Center: (0.0/2.0/0.0)

    Scale: 1.0 0.5 1.0

    Material: mat1

Created sphere 'kugel2:

    Radius: 1.0

    Center: (5.0/1.0/6.0)

    Scale: 1.0 1.0 1.0

    Material: bam

 ---

Finished with creating scene within 137ms! Closing scene file...

Starting to render...



weiterhin werden alle objekt transformationen in matrizen gespeichert. jedes objekt lässt sich neben verschieben jetzt auch in jede richtung strecken und rotieren. zwar ist das noch ein wenig buggy, aber ich arbeite zur zeit heftig daran.

ich möchte noch erwähnen, dass ich den source bald, wenn das grundgerüst steht und ich ein wenig dokumentation geschrieben habe, ihn unter der GPL-Lizenz veröffentlichen möchte und vielleicht hat ja dann der eine oder andere lust vlt einen shader zu coden oder iwie anders dabei einzusteigen. würde mich zumindest freuen. bis dahin ist aber noch ein wenig arbeit für mich zu schaffen.

grüße darren

PS: kommentare und vor allem kritik sind immer willkommen!

Planung geht immer weiter!

Samstag, 7. Februar 2009 von Darren
Guten Abend liebe Leser!

Ersteinmal möchte ich mich für das viele Feedback hier in den Kommentaren bedanken. Toll, dass ich alle mal mein etwas sinnfreies Programm trotzdem getestet habt. Dickes Lob an euch!

Die Planung schreitet voran und hat mich dazu gebracht ein weiteres mal die Arbeit von neuem zu beginnen, aber diesmal VIEL geplanter, als selbst bei anlauf 2. Ich habe jetzt ein sehr modulares material-system entworfen, habe mir gedanken, über das traceit!-datei-format gemacht.
Ich hab vor ganz von Anfang an darauf zu setzen, dass man sich selbst dateien scripten kann, die dann gerendert werden. vielleicht hat ja dann jemand lust und schreibt einen exporter für irgendein 3d-programm.

Die grundstruktur des Raytracers habe ich mir auch noch einmal durch den kopf gehen lassen. Konkretes dazu gibt es vielleicht morgen abend. weiterhin habe ich matrizen fest mit eingeplant, welche dann vor allem wichtig werden, wenn es um polygonale objekte geht. denn eigentlich muss beim schnittpunkttest der strahl in die lokalen koordinaten des objektes transformiert werden. und der schnittpunkt muss schließlich wieder zurücktransformiert werden. genauso mit der normale. man muss sich also für jedes objekt eine transformationsmatrix speichern, sowie eine matrix für die rücktransformation. das mathematische wissen hierfür muss ich mir aber noch aneignen. ich hab zwar das prinzip verstanden, aber bis ich das codemäßig umsetzen kann, muss ich es gedanklich noch ein wenig weiter durchdringen.

ein weiteres primitive ist hinzugekommen! der Würfel. mit dem kann ich dann ausgiebig die Funktionalität meiner matrizen testen, denn vor allem rotationsabbildungen hätte ich weder mit kugeln, noch mit ebenen testen können.

angefangen habe ich mit einer sehr grundlegenden mathe-bibliothek, die lediglich einen type definiert, den vektor und lässt mich recht bequem und übersichtlich einige elementare vektor-rechnungen durchführen. zwar ist es deutlich schneller solche operationen ohne types und direkt im code zu vollziehen, aber types sind in BB einfach meiner meinung nach der sinnvollste weg daten zu organisieren und zusammenzuhalten.

Jetzt aber genug geblubbert. hier mal einige ergebnisse meiner planung:

Vektor-Bibo:
Code: [AUSKLAPPEN]

;math.bb
Type vec
   Field x#[2]
End Type

Function vec_scale(k#,a.vec)   
   a\x[0] = k * a\x[0]
   a\x[1] = k * a\x[1]
   a\x[2] = k * a\x[2]   
End Function

Function vec_length#(a.vec)
   Local length#   
   length = a\x[0]^2 + a\x[1]^2 + a\x[2]^2   
   length = Sqr(length)      
   Return length   
End Function

Function vec_normalize.vec(a.vec)
   Local faktor#
   faktor = 1/(vec_length(a.vec))
   a.vec = vec_scale(faktor,a.vec)   
   Return a.vec   
End Function

Function vec_scal_prod#(a.vec,b.vec)
   Local scal_prod#   
   scal_prod =(a\x[0]*b\x[0]) + (a\x[1]*b\x[1]) + (a\x[2]*b\x[2])   
   Return scal_prod
End Function

Function vec_cross_prod.vec(a.vec,b.vec,c.vec)
   c\x[0] = a\x[1]*b\x[2] - a\x[2]*b\x[1]
   c\x[1] = a\x[2]*b\x[0] - a\x[0]*b\x[2]
   c\x[2] = a\x[0]*b\x[1] - a\x[1]*b\x[0]
   Return c.vec
End Function

Function vec_print$(a.vec)
   Local komps$ = "(" + a\x[0] + "|" + a\x[1] + "|" + a\x[2] + ")"
   Return komps
End Function


hier ein grober entwurf eines shaders:
user posted image

Aufbau des Szenenformates
user posted image
user posted image
user posted image
user posted image

So long Leute! Kommentare sind wie immer erwünscht. genauso wie fragen das thema betreffend!

Genauere Planung geht voran

Montag, 2. Februar 2009 von Darren
Guten Tag!

Ich habe jetzt beschlossen die Schulzeit unter der Woche hauptsächlich der Planung mit Bleistift und Papier zu widmen. Dabei habe ich mir gedanken darüber gemacht, wie ich am sinnvollsten alle Daten, die benötigt werden um die Szene und alles was darin enthalten ist, zu beschreiben.

Erst einmal habe ich das was wirklich sichtbar ist, in zwei bereiche eingeteilt: Objekte und Lichtquellen. Die Idee alles was in der Szene enthalten ist erst einmal unter einem vollkommen allgemeinen Objekt zusammenzufassen schien mir doch ein wenig zu übertrieben und zu viel des guten.

Doch da ich keine lust habe, alles hier in Wort zu fassen, habe ich mit Freemind mal schnell zwei mindmaps gemacht. Die eine versucht mir einen groben eindruck davon zu ermitteln, was alels in die szene gehört und die andere erklärt den aufbau meines "materialsystems". Das ist noch ziemlich rudimentär, kann aber durch die getrennte handhabung von shadern und Material selbst sehr gut erweitert werden.

Hier die Mindmap für die Szenen-Struktur:
user posted image

Hier die Mindmap des material-systems:
user posted image

Allgemein muss ich sagen, dass dieses Programm sehr nützlich ist, wenn man seine ganzen Ideen organisieren will. Ich kann es nur jedem empfehlen es sich einmal zu besorgen und die paar Minuten zur einarbeitung aufzubringen. es lohnt sehr!

Desweiteren, habe ich mal eine To-Do-List angefertigt, die ich von oben nach unten abarbeiten will. die einträge sind ale nach priorität geordnet:
Arrow Strahl-Qader-Schnittpunkt-Algo
Arrow Nebel
Arrow Transformationsmatrizen für Objekte
Arrow Material- und Shadersystem
Arrow Sperical-Texture-Mapping
Arrow Bumpmapping
Arrow Flächenlichtquellen
Arrow Distributed Raytracing(Flächenschatten, Depth Of Field)

Sodele, jetzt hab ich mir aber echt sehr viel Mühe für diesen Eintrag hier gegeben. Kommentare sind immer erwünscht!

Bugfixes und Speedups!

Sonntag, 1. Februar 2009 von Darren
Guten Abend!

Es gibt diesmal keine neuen Features zu melden, sondern nur ein paar sinnlose bugfixes und speedups.

einen bug kann man hier sehen, mit einem vorher/nacher vergleich:

user posted image

weiterhin, habe ich mal eine exe kompiliert, bei der man auflösung des bilder eingeben kann. Dann werden 10 Kugeln zufällig erstellt und gerendert.

Vielleicht könntet ihr ja mal auflösung+renderzeit+prozessor posten?

hier der DL:
http://dl.getdropbox.com/u/416097/main.exe
(wie immer vorsichtig. es kann immernoch zu abstürzen kommen, also bitte keine ungespeicherten docs offen haben!)

kompletter rewrite

Freitag, 30. Januar 2009 von Darren
so hallo leute!

ich habe mich die letzte woche damit befasst, meinen raytracer nochmal komplett neu zu schreiben. jetzt funktioniert auch die iteration und somit is jetzt der weg frei für reflexion und transmission. folgende features gibt es jetzt:

Arrow Zwei primitives (kugel, ebene)
Arrow kameramodell: beliebiges vertikales field of view, beliebige auflösung
Arrow diffuse reflexion(lambertsches gesetz)
Arrow specular (nach phong)
Arrow raytraced shadows(harte schatten)
Arrow reflexion (fresnel ist noch geplant)
Arrow ambientlight

hier nochn screen:
user posted image

Projektplanung!

Dienstag, 27. Januar 2009 von Darren
Wie schon im WIP erwähnt, habe ich mich für meine Facharbeit (Abiturient in Bayern - Kniet nieder!) mit den grundlegenden Algorithmen des Raytracings befasst. Mein aktueller Kenntnisstand beträgt ungefähr das Wissen der Forschung aus dem Jahre 1960/70 als Raytracing zum ersten mal vorgestellt wurde, aber aufgrund von mangelnder Rechenleistung nicht weiter erforscht.

Damals gab es bereits Ansätze für das Iterative Vorgehen, um Phänomene wie Reflexionen oder Transmissionen darstellen zu können.

Um nicht nur bei der Theorie hängen zu bleiben, habe ich beschlossen einmal ein Projekt zu beginnen, das zum Ziel hat einen möglichst stabilen raytracer zu entwickeln. dabei geht es mir erst einmal nicht um speed, sondern um eine saubere umsetzung der algos in BB. Wahrscheinlich ist Blitz Basic nicht die richtige Sprache für einen wirklich umfangreichen und schnellen Raytracer, doch es geht mir eh nicht darum irgendeinem anderen Projekt der Art konkurenz zu machen, sondern ich interessiere mich einfach für die methoden die hinter einem meiner hobbies stecken.

Ich hab jetzt erst einmal mit der Planung angefangen, um mir eine grobe Struktur des Raytracers zu verdeutlichen. dazu habe ich mal freemind verwendet, und bin zu folgendem ergebnis gekommen:

http://dl.getdropbox.com/u/416097/struktur.html

Wer sich meine Facharbeit zu dem Thema ansehen will, kann das hier mittels PDF machen:

http://dl.getdropbox.com/u/416097/fa_final.pdf

Im zuge meines ersten posts, möchte ich auch bekannt geben, dass ich vor habe den ganzen code immer offen zu halten, unter der GPL-Lizenz. Jeder kann dann den code nehmen und gemäß der GPL-Lizenz damit umgehen. Ich werde mich aber dahingehend noch informieren.
Weiterhin möchte ich hiermit verlauten lassen, dass ich gerne bereit bin ein kleines team zu gründen, um mehrere helfende finger und köpfe dabei zu haben. wer will kann sich zu jedem zeitpunkt in das projekt einklinken und genauso einfach wieder ausklinken. ich bin sicher nicht perfekt was meinen code-stil und meine geistigen fähigkeiten angeht, deshalb bin ich für jede hilfe dankbar.

doch es ist ein projekt, das ich schon immer einmal beginnen wollte. jetzt ist die zeit gekommen, und ich werde sicher nicht aufgeben. zumindest nicht kurz- oder mittelfristig!

danke für eure aufmerksamkeit erst einmal!