I'm writing a simple raycaster in golang and I have some problems understanding perspective correction. The code is simple, the main rendering loop is this:
curVector := playerVector.NewRotated(-curFov / 2)
rotateStep := curFov / float64(screen.Width()) // Angles per screen row
// Traverse each row of our screen, cast a ray and render it to screen buffer
for i := 0; i <= screen.Width(); i++ {
curVector.Rotate(rotateStep)
hit, distance, tile, tileP := rayCast(curX, curY, curVector, viewDistance)
if hit {
// distToHeight is basically linear (screen.Height()/distance)
drawTexturedWallColumn(screen, tile, i, distToHeight(distance, screen.Height()), tileP) // Project walls on screen
}
// drawSpritesColumn(screen, i, curVector, distance) // Project sprites on screen
}
So I just cast rays with even angle intervals and get this fishbowl effect:
So, I understand that the problem is with angle intervals and sphere projected rays with the same length. I found this question How can I correct an unwanted fisheye effect when drawing a scene with raycasting? and tried to implement the same logic:
leftVector := playerVector.NewRotated(90)
// Traverse each row of our screen, cast a ray and render it to screen buffer
for i := 0; i <= screen.Width(); i++ {
progress := float64(i)/float64(screen.Width()) - 0.5 // -0.5 to 0.5
stepX := (playerVector.X + progress*(leftVector.X*2)) // *2 to make 90 FOV
stepY := (playerVector.Y + progress*(leftVector.Y*2))
curVector := Vector{X: stepX, Y: stepY}
hit, distance, tile, tileP := rayCast(curX, curY, curVector, viewDistance)
if hit {
// distToHeight is basically linear (screen.Height()/distance)
drawTexturedWallColumn(screen, tile, i, distToHeight(distance, screen.Height()), tileP) // Project walls on screen
}
// drawSpritesColumn(screen, i, curVector, distance) // Project sprites on screen
}
But the result is almost the same (FOV variable is not used here but it's around 90, it's not important at the moment). The difference is that this one has a more "linear" fishbowl effect because of evenly spaced intervals (progress variable):
So, I don't know how to fix this, I also tried to use perpendicular distance (distance*cos).