PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : Raytracing-Problem


Gast
2008-04-26, 19:48:40
Hi Folks,

ich wollt mir grad mal n Raytracer programmieren, und bin dabei auf ein Problem gestossen (ein Kommilitone hatte das gleiche Problem, bei google find ich dazu nichts).
Das Problem ist, dass das Bild zum Rand hin immer mehr verzerrt wird, was vermutlich dadurch verursacht wird, dass man einen dreidimensionalen Raum auf eine zweidimensionale Flaeche abbildet.
Aber auch, als ich versucht habe, den Raum auf eine Kugeloberflaeche abzubilden (mal n bisschen mit tangens draufschiessen), sind verzerrungen aufgetreten - nur diesmal wurde es gestaucht statt gestreckt.

Beispiele:
erste Versuche mit Python (man war das langsam ^^), mit tangens (also versucht auf ne Kugelflaeche abzubilden):
[img=http://img237.imageshack.us/img237/3540/bospheresoi7.th.png] (http://img237.imageshack.us/my.php?image=bospheresoi7.png)

Dann mit C#, ich hab schnell was zusammengefrickelt, damit ich seh obs wieder verzerrt, deshalb ist Licht o.ae. nicht beruecksichtigt:
[img=http://img261.imageshack.us/img261/491/bladt1.th.png] (http://img261.imageshack.us/my.php?image=bladt1.png)

(es sollten nur Kugeln dargestellt werden)

Technik: Aufpunkt und Richtungsvektor fuer die Kamera, von da aus dann jeweils ein Vektor durch jeden Bildpunkt der Bildebene (x und y interpoliert).

Meine Frage ist jetzt: Was mache ich (bzw. was machen wir) falsch? Gibt es da irgendwelche trivialen loesungen dafuer, oder eine (meinetwegen auch ausfuehrliche) Anleitung, wie man das loswird bzw. wie man einen Raytracer von Anfang an aufzieht?

Ich wuerde mich sehr ueber Antworten und/oder Links zum Thema freuen (-:

Gruss,
Leo

PS1: ich habe sonst noch keine Erfahrung mit 3D-Programmierung.
PS2: Ich find's toll, dass man sich hier nicht gleich Registrieren muss (-:

Gast
2008-04-26, 20:34:28
Konkret kann ich dir auch nicht sagen was falsch ist, da ich selbst keine Erfahrung in diesem Bereich habe. Kann dich nur auf die Raytracing Serie (http://www.devmaster.net/articles/raytracing_series/part1.php) auf DevMaster.net verweisen. Diese habe ich einmal gelesen, und sie sieht ganz gut aus.

mfg squall23

Coda
2008-04-26, 20:42:51
Ihr macht nichts falsch. Das Ergebnis ist entspricht völlig des zu erwartenden.

Gast
2008-04-26, 21:05:32
Kann man erst sagen wenn du mal den coden mit dem du die Strahlen generierst zeigst.

Gast
2008-04-26, 21:29:27
Ihr macht nichts falsch. Das Ergebnis ist entspricht völlig des zu erwartenden.
Ahja. Ich meinte mehr Falsch im Sinne dessen, was ich erreichen will.
Und diese Verzerrung ist auf jeden Fall nicht das, was ich will - ich mein wenns ein wenig verzerrt ist, ist das ja vielleicht ok - verstaerkt vielleicht noch den "3D-Effekt". Aber das ist zu viel (und auf anderen Bildern, die mit Raytracing erstellt wurden ist ja auch nicht so eine Verzerrung drauf).

Hier mal der Kot fuer die Rays:

// ein Ray-Objekt ist nichts weiter als ein Vektor und ein Aufpunkt
this.rays = new Ray[Convert.ToInt32(this.screen[0]) * (antialiasing),
Convert.ToInt32(this.screen[1]) * (antialiasing)];

// Mittelpunkt der Bildebene (screen) - screen[2] enthaelt die information, wie weit es von der Kamera zur Bildebene ist;
//position ist die position der Kamera, direction der Richtungsvektor fuer die Kamera
double[] center ={ this.position[0] + this.screen[2] * this.direction[0],
this.position[1] + this.screen[2] * this.direction[1],
this.position[2] + this.screen[2] * this.direction[2] };

for (int x=0; x < this.screen[0]; x += 1)
{
for (int y=0; y < this.screen[1]; y += 1)
{
//(center+screen_size)-position
double[] ray_pos ={ center[0] - (this.screen[0] / 2) + x,
center[1] - (this.screen[1] / 2) + y,
center[2] };
double[] ray_vec ={ ray_pos[0] - this.position[0],
ray_pos[1] - this.position[1],
ray_pos[2] - this.position[2] };
this.rays[x, y] = new Ray(vec.normform(ray_vec), ray_pos);
}
}

Gast
2008-04-27, 10:00:53
Ich bins nochmal.

Im codeauszug hat sich noch ein "antialiasing" eingeschlichen, vergesst das einfach, die implementierung davon ist eh falsch (und hat keine Auswirkung, da es im Testfall 1 ist).

Kann es sein, dass die einzige Moeglichkeit, die Verzerrug zu minimieren, ist, den Abstand von Kamera zu Bildebene zu maximieren? Mir persoenlich gefaellt diese Idee gar nicht, da koennte man genausogut fuer jeden Pixel einen Strahl aussenden, der senkrecht auf der Ebene steht.

Gruss,
Leo

del_4901
2008-04-27, 10:14:04
Das heißt ja noch lange nicht das es keinen Brennpunkt mehr gibt. Wenn der Abstand zur Bildebene gering ist, hast du einen Weitwinkel oder gar Fischauge drauf. Schiebst du die Bildebene weiter weg, bekommst du eine Teleobjektiv. Wie bei einer richtigen Kamera halt, nur das man da nicht die Bildebene verschieben kann, und stattdessen das Objektiv austauscht.
Ich weiß ja nicht wie weit fortgeschritten du schon bist, aber man geht bei einem Raytracer sogar soweit das man ein Objektiv mit verstellbarer Blende simulliert. Am Anfang hat man ja meißt nur ein Lochkamera Prinzip.

Xmas
2008-04-27, 15:51:19
Ahja. Ich meinte mehr Falsch im Sinne dessen, was ich erreichen will.
Und diese Verzerrung ist auf jeden Fall nicht das, was ich will - ich mein wenns ein wenig verzerrt ist, ist das ja vielleicht ok - verstaerkt vielleicht noch den "3D-Effekt". Aber das ist zu viel (und auf anderen Bildern, die mit Raytracing erstellt wurden ist ja auch nicht so eine Verzerrung drauf).
Das Problem ist dann wohl schlicht, dass du ein zu großes FOV (field of view) verwendest. Bei normalem Betrachtungsabstand füllt ein Monitor (bzw. das Bild darauf) ja nur einen relativ kleinen Winkel (vielleicht 40°) im Blickfeld. Bei der Projektion einer dreidimensionalen Szene nutzt man in der Regel aber einen deutlich größeren Winkel, weil sonst der Eindruck überwiegen würde durch ein kleines Fenster zu schauen. Insbesondere bei Spielen kommt es mehr auf die Übersicht denn auf die "korrekte" Darstellung an.

Dadurch das tatsächliches Blickfeld und virtuelles Blickfeld nicht übereinstimmen nimmt man das Resultat als verzerrt wahr.