Wie Rechnen? Geometrie/Vektoren/etc

Es gibt 7 Antworten in diesem Thema. Der letzte Beitrag () ist von FreakJNS.

    Wie Rechnen? Geometrie/Vektoren/etc

    Hallo^^
    Ich hänge schon länger an einem Problem und stehe einfach auf dem Schlauch. Es geht um meine Raycasting-Engine, ich will Sprites einbauen, die nicht immer parallel zur ProjectionPlane sind bzw der Kamera immer zugewendet. Man kann sich das Sprite also vorstellen wie eine große freistehende Wand um die man herumlaufen kann. Um ein solches Sprite zu rendern brauche ich von jedem Ray der von der Cam ausgeht, dann die ProjectionPlane "ganzzahlig schneidet" (das sind die späteren Pixel, es gibt eben keine halben Pixel, nur Ganze) und irgendwann auf das Sprite trifft diverse Informationen:

    - durch welchen "Pixel"/Zahl der ProjectionPlane läuft der Ray?
    - Distanz: Distanz zwischen Cam und Treffpunkt des Rays auf dem Sprite
    - TexScaleFactor: Ein Sprite ist immer 1 Einheit groß und der TexScaleFactor gibt an wo das Sprite relativ zu einer seiner Ecken getroffen wurde. Es werden also Werte zwischen 0 und 1 erzeugt

    Die Cam-Rotation wird übrigens vorher "rausgerechnet" und spielt somit keine Rolle, genau wie die Cam-Position. Die Cam ist der Ursprung des Koordinatensystems und vereinfacht so das Rechnen. Nur das Sprite hat einen Variablen Winkel. Sprites die sich "links" von der Kamera befinden müssen nicht gerendert werden.

    Den Start- und EndPixel (auf der ProjektionPlane) kann man einfach bestimmen. Man kennt P1 und P2. Also gilt:
    dtPP / offsetPP = P.x / P.y

    offsetPP ist dann der Pixel auf der ProjectionPlane, für die obere Grenze muss man auf eine ganze Zahl aufrunden, für die untere Grenze einfach abrunden. Nur für die Rays zwischen Oberer und Untere Grenze kommt ein Treffpunkt auf dem Sprite in Frage.

    Hat irgendjemand Ideen wie man das Problem (am besten auch noch performant :thumbsup: ) lösen könnte? Hatte bisher ein paar Ansätze ausprobiert (zielten eigentlich immer darauf ab irgendwo lerpen zu können, dass funktioniert aber leider nie...). Gibt es vllt irgend eine Vektor/Matrix-Keule? Wäre richtig froh, wenn das mal funktioniert xD

    lg
    Bilder
    • skizze.jpeg

      273,65 kB, 1.986×1.242, 221 mal angesehen
    Beschreib doch mal bitte exakt, was du berechnen möchtest. Für gewöhnlich berechnet man für jeden Pixel der Projektionsfläche erst mal die Gerade durch Kamera* und Pixelmittelpunkt und schaut, welche Facette von der Kamera aus betrachtet am nächsten hinter der Projektionsfläche liegt. Wobei brauchst du jetzt Hilfe? ;)

    * Wenn die Kamera eine Lochkamera ist und die Darstellung dadurch perspektivisch, wonach es bei dir im Bild stark aussieht.

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „Renati“ ()

    Hi^^
    Raycasting ist ja nur "Pseudo-3D", die Draufsicht (meine Skizze) alleine liefert also genug Information um die Projektion eines Sprites zu berechnen. Das Render-Ergebnis wird also Spaltenweise aufgebaut (Auflösung 320x240 bedeutet also, dass man 320 Spalten hat und jede Spalte 240 Pixel hoch ist). Die Linie die von der Cam durch die Pixelmitte verläuft nenne ich Ray, nur das es keine Verwirrung stiftet^^ Ich brauche also drei Informationen um eine Pixelspalte zu erzeugen:

    - den Index der Pixelspalte (also die Zahl, die an "ProjectionPlane" steht). Das ist das, was du als Pixelmittelpunkt beschreibst.
    - Die Linie die von der Kamera ausgeht, durch diesen Pixelmittelpunkt läuft und irgendwann auf das Sprite trifft hat eine Länge. Diese Länge brauche ich um die Höhe der Projektion zu berechnen (das ist aber ein bereits gelöstes Problem, ich brauche nur die Distanz)
    - Die Linie trifft irgendwo auf das Sprite. Ich muss wissen wie weit der Treffpunkt von P1 entfernt ist. Da das Sprite 1 Einheit lang ist kann dieser Wert (TexScaleFactor) nur zwischen 0 und 1 liegen. Diesen Faktor brauche ich um der Projektion (genauer gesagt der Pixelspalte, denn ein Ray liefert Informationen für eine Pixelspalte) die entsprechende Textur-Spalte zuzuweisen.

    Wie gesagt, ich brauche nur diese drei Werte, der Rest ist fertig^^ Meine aktuelle Implementation ist gebastel pur und macht das alle über die Winkel - liefert Ergebnisse, allerdings will ich es jetzt richtig machen. Linear interpolieren funktioniert wie gesagt nicht: Du wirst feststellen, dass die WinkelUnterschiede mit zunehmenden RayIndex (das was an ProjectionPlane steht) immer kleiner werden.. Hoffe das war halbwegs verständlich.

    Ich brauche also nur Hilfe die drei besagten Werte zu berechnen - mir würde schon reichen, wenn ich ein paar Gleichungen hätte, die sich auch so implementieren lassen, dass die CPU keine zehn Sekunden braucht xD Alles über Winkel, Sinus und Cosinus laufen zu lassen ist einfach aber kostet zuviel Zeit.

    Edit: Ich denke eine Lochkamera funktioniert genau umgekehrt: dort werden Strahlen durch das Loch "geordnet", sodass sie beim Auftreffen auf den Schirm ein Bild ergeben. Bei mir werden gezielt Strahlen ausgesendet (von der Cam-Position durch die Pixelmitten des Schirms bzw der ProjectionPlane). Das Bild ensteht durch die Informationen die der ausgesendete Ray liefert...

    lg

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „FreakJNS“ ()

    Ich meine Raycasting (im Sinne von einem stark vereinfachten Raytracing). Hier ist eine recht gute Gegenüberstellung:
    permadi.com/tutorial/raycast/r…STING%20AND%20RAY-TRACING

    Ich habe nicht vor durch jeden Pixel des Bildschirms einen Ray zu jagen, sondern nur einen je Pixelspalte. Selbst Doom1/2 basiert auf Raycasting, allerdings wurde das Prinzip da stark ausgeweitet. Trotzdem ist die komplette Map "nur" 2D. So ist es nicht möglich zwei begehbare Ebenen übereinander zu legen.
    Den Index einer Spalte bekommst du in dem Moment, wo du einen Strahl dadurch sendest. Für den Strahl stellst du eine Geradengleichung auf. Mittels der Geradengleichung bestimmst du den Schnittpunkt mit deinem Sprite. Dann kannst du mit der euklidischen Distanz die Länge der Strecke zwischen Kamera und Schnittpunkt bestimmen. Aus dem Schnittpunkt kannst du auch den Abstand zu P1 bestimmen.
    Warum die Berechnung über Winkel aber nun einfach(er) sein soll, leuchtet mir nicht ein. ;)

    FreakJNS schrieb:

    Edit: Ich denke eine Lochkamera funktioniert genau umgekehrt: dort werden Strahlen durch das Loch "geordnet", sodass sie beim Auftreffen auf den Schirm ein Bild ergeben. Bei mir werden gezielt Strahlen ausgesendet (von der Cam-Position durch die Pixelmitten des Schirms bzw der ProjectionPlane). Das Bild ensteht durch die Informationen die der ausgesendete Ray liefert...

    Das macht bei einer idealen Lochkamera keinen Unterschied. Das Grundmodell für perspektivische 3D-Grafik ist das einer Lochkamera, bei der die Bildfläche auf die andere Seite der Kamera gespiegelt wird. Eigentlich habe ich das nur erwähnt, um das von paralleler Projektion abzugrenzen, bei der man einfach die Bildebene hat, von der aus man orthogonal dazu verlaufende Strahlen aussendet.
    Boah!! Ich hätte schwören können, dass "normale" Geradengleichungen zu Humbuk führen - hätte mal besser nochmal drüber nachgedacht, denn senkrechte Rays gibt es garnicht. Habe mich deshalb so auf Vektoren verbissen^^ Habe zwischenzeitlich eine entsprechende Lösung gemacht, allerdings ist da der Wurm drin. Darum habe ich deinen Vorschlag mal schnell in mein Tesprogramm gehackt - und siehe da, es scheint zu funktionieren!!!



    Vielen Dank für den kleinen aber sehr wirkungsvollen Denkanstoß!

    Edit:


    Jetzt nur noch optimieren^^

    Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von „FreakJNS“ ()