Raycaster - Textur verzogen

Übersicht BlitzMax, BlitzMax NG Allgemein

Neue Antwort erstellen

Trust

Betreff: Raycaster - Textur verzogen

BeitragSa, März 01, 2014 16:45
Antworten mit Zitat
Benutzer-Profile anzeigen
Hallo,

lang ists her, nun hab ich mal wieder etwas Zeit gefunden, meinem Hobby nachzugehen.

Rein aus Interesse, wollte ich mich mal ein bisschen mit dem Thema Raycasting beschäftigen. -> http://de.wikipedia.org/wiki/Raycasting

Funktioniert auch einigermaßen gut.

Nur habe ich das Problem: sobald sich der Spieler zu nah auf eine Wand zubewegt, also schon direkt davor steht, sich die "Textur" auf der Wand stark verzieht. Ich komme einfach nicht drauf, woran das liegen könnte.

Hier mal ein paar Bilder dazu, um es verständlicher zu machen:

Spieler ist weit weg von der Wand: (alles noch in Ordnung)
user posted image

Spieler kommt der Wand näher: (immer noch alles gut)
user posted image

Spieler steht direkt an der Mauer:("Textur" verzieht sich sehr stark)
user posted image

Da ich überhaupt nicht weiß, wo das Problem liegt, weiß ich auch nicht, welchen Codeabschnitt ich dazu posten soll. Wenn gewünscht, kann ich den kompletten Code nachreichen.

Vielen Dank
MfG Trust
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.

DAK

BeitragSa, März 01, 2014 21:12
Antworten mit Zitat
Benutzer-Profile anzeigen
Hast du irgendeinen anderen Shader den du statt dem Texturshader verwenden kannst um herauszufinden, ob es am Shader oder am sonstigen Code liegt?
Gewinner der 6. und der 68. BlitzCodeCompo

Trust

BeitragSa, März 01, 2014 22:05
Antworten mit Zitat
Benutzer-Profile anzeigen
Ich weiss jetzt nicht genau, was du mit "Shader" meinst.
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.

DAK

BeitragSa, März 01, 2014 23:20
Antworten mit Zitat
Benutzer-Profile anzeigen
Ok, wie bestimmst du, perspektivisch korrekt welches Pixel der Textur wo am Bildschirm landet?
Das sollte üblicherweise in einem Shader passieren.

Hast du eventuell eine Variante gebaut, wo du untexturierte Objekte anzeigen kannst? Am besten Mehrfarbige oder welche mit Farbüberlaufen? Wenn ja, tritt das Problem dort immer noch auf?

Tritt das Problem auch auf, wenn du zwei verschiedenfarbige jeweils einfarbige Objekte direkt nebeneinander stellst?

Kannst du eventuell die genaue Funktionsweise deines Raycasters beschreiben?
Gewinner der 6. und der 68. BlitzCodeCompo

Trust

BeitragSo, März 02, 2014 1:39
Antworten mit Zitat
Benutzer-Profile anzeigen
Ach so ok.
Also bei diesem Raycaster wird nicht jeder Pixel einzelnd berechnet (ist glaub ich auch üblich so, denn sonst wäre es Raytracing wenn ich das richtig verstanden habe) sondern "streifenweise".
Also für jede X-Koordinate ein ausgesendeter Strahl.
Bei einer Auflösung von 800 x 600 wären das 800 Streifen bzw. ausgesendete Strahlen.
Und jenachdem, welche Länge dieser Strahl hat (Distanz zur Mauer), wird dementsprechend von weiter oben angefangen, die Mauer auf den Bildschirm zu zeichnen.
Umso weiter weg die Mauer, desto kleiner wird sie auf den Bildschirm gezeichnet und umgekehrt.
Das alles natürlich in Abhängigkeit zum Blickwinkel des Spielers.

Hier einmal der Code, welcher auswertet, wo der Strahl die Mauer getroffen hat (X-Koordinate) und dementsprechen den dazugehörigen, ein Pixel breiten, vertikalen Streifen von der Textur, auf den Bildschirm zeichnet.

BlitzMax: [AUSKLAPPEN]

' DDA (Digital Differential Analyzer - Rasterung von Linien)
While hit = 0
' springe zum nächsten Quadraht, oder in X-Richtung oder in Y-Richtung
If sideDistX < sideDistY
sideDistX = sideDistX + deltaDistX
mapX = mapX + stepX
side = 0
Else
sideDistY = sideDistY + deltaDistY
mapY = mapY + stepY
side = 1
End If

' Überprüfe ob Strahl eine Mauer getroffen hat
If Map[mapX, mapY] > 0 Then hit = 1
Wend


' Berechnet die Distanz zur Kamerarichtung (normale distanz verursacht den sog. fisheye effect!)
If side = 0
perpWallDist = Abs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX)
Else
perpWallDist = Abs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY)
End If



' Berechnet die Höhe der Linie um sie auf den Bildschirm zu zeichnen
Local lineHeight:Int = Abs(Int(h / perpWallDist))


' Berechnet den niedrigsten und höchsten Pixel um den aktuellen Streifen zu füllen
Local drawStart:Int = -lineHeight / 2 + h / 2
If drawStart < 0 Then drawStart = 0
Local drawEnd:Int = lineHeight / 2 + h / 2
If drawEnd >= h Then drawEnd = h - 1


' Berechnet den X-Wert der Mauer
Local wallX:Float ' wo genau die Mauer vom Strahl getroffen wurde
If side = 1
wallX = rayPosX + ((mapY - rayPosY + (1 - stepY) / 2) / rayDirY) * rayDirX
wallX = wallX - Floor((wallX))
Else
wallX = rayPosY + ((mapX - rayPosX + (1 - stepX) / 2) / rayDirX) * rayDirY
wallX = wallX - Floor((wallX))
End If


' x Koordinate auf der Textur
Local texX:Int = Int(wallX * Float(texWidth))
If side = 0 And rayDirX > 0
texX = texWidth - texX - 1
End If
If side = 1 And rayDirY < 0
texX = texWidth - texX - 1
End If


' Zeichnet die Pixel des Streifens als vertikale Linie
DrawSubImageRect(Texture[0], x, drawStart, 1, drawEnd-drawStart, texX, 0, 1, texHeight)
Es gibt 10 Gruppen von Menschen: diejenigen, die das Binärsystem verstehen, und die anderen.

Neue Antwort erstellen


Übersicht BlitzMax, BlitzMax NG Allgemein

Gehe zu:

Powered by phpBB © 2001 - 2006, phpBB Group