Page 1 of 1
Raycaster Issues (Horizontal Checking)
Posted: Tue Mar 28, 2023 10:07 am
by NoreoAlles
Hi, i´ve been trying to make a Raycaster in Löve and i need help because (1) my rays are kindof cluttered and (2) my rays dont care if they´ve hit a wall sometimes and (3) the rays sometimes all go right when my player is facing left and near to a wall in the right direction.
I´ve tried to comment most of the stuff.
Any help would be appriciated
Re: Raycaster Issues (Horizontal Checking)
Posted: Tue Mar 28, 2023 12:01 pm
by Bigfoot71
There are a number of choices that I haven't really been able to understand in your code, so I took the liberty of completely rewriting the function to better understand the concept, here's what it might look like (I've part removed point storage in hits):
Code: Select all
function RayCast(ray_step_size, num_rays)
num_rays = num_rays or screen_width
ray_step_size = ray_step_size or 5
local angle = P.a - fov / 2
local step = fov / (num_rays - 1)
love.graphics.setColor(1, 0, 0) -- We apply the line color only once
for i = 1, num_rays do
local sin_a = math.sin(angle)
local cos_a = math.cos(angle)
local x = P.x
local y = P.y
local distance_to_wall = 0
local hit_wall = false
while not hit_wall do
local map_x = math.floor(x / tile_size) + 1 -- Round ray pos to map pos
local map_y = math.floor(y / tile_size) + 1
if map[map_y][map_x] == 1 then -- If the step of the ray is in a wall
distance_to_wall = math.sqrt((x - P.x) ^ 2 + (y - P.y) ^ 2) -- We calculate the distance
hit_wall = true -- This value is used for understanding the code
break -- We could do without it since we break just after
end
x = x + cos_a * ray_step_size -- Next raystep
y = y + sin_a * ray_step_size
if x < 0 or y < 0 or x > map_width * tile_size or y > map_height * tile_size then -- Security if you leave the map
break
end
end
-- Draw the red line to the nearest wall --
local line_end_x = P.x + cos_a * distance_to_wall
local line_end_y = P.y + sin_a * distance_to_wall
love.graphics.line(P.x, P.y, line_end_x, line_end_y)
-- We go to the next angle step (next ray) --
angle = angle + step
end
end
It's still a version that I also tweaked personally, there are many courses on raycasting that cover even more optimized techniques, but I think what I wrote is quite simple to understand, if you have any questions. don't hesitate.
Otherwise maybe someone more knowledgeable than me could say more because I don't want to lose you. When I'm gone I don't stop anymore
Here is the result with ray_step_size = 0.1 (px) and ray_nums = 45:
And the result with the default parameters, i.e. ray_step_size = 5 (px) and ray_nums = screen_width:
(Don't pay attention to the FPS counter which varies a lot, I'm on an old machine and I was filming, without filming it remained rather stable for me)
Re: Raycaster Issues (Horizontal Checking)
Posted: Tue Mar 28, 2023 3:08 pm
by NoreoAlles
Thank you so much, that is so much cleaner then what i tried. I tried to skip the "extend ray by this size" part and tried to just do it super optimized without really understanding what i was doing. I´ll tell you if i have any more problems, but this just looks great. (:
Re: Raycaster Issues (Horizontal Checking)
Posted: Tue Mar 28, 2023 3:50 pm
by NoreoAlles
I quickly made it render in 3d, thought you might want to see. I´ll later fix the fisheye and maybe make a full game out of this and post it here on the forums. I for now have copied your code exactly but i will ofc change it later on, hope you dont mind
Re: Raycaster Issues (Horizontal Checking)
Posted: Tue Mar 28, 2023 3:52 pm
by Bigfoot71
NoreoAlles wrote: ↑Tue Mar 28, 2023 3:08 pm
Thank you so much, that is so much cleaner then what i tried. I tried to skip the "extend ray by this size" part and tried to just do it super optimized without really understanding what i was doing. I´ll tell you if i have any more problems, but this just looks great. (:
This code that I proposed remains as an example to fully understand the principle, I have kept it as simple as possible so as not to confuse you so it is very largely optimizable.
Besides the values that are recalculated on each call to the function, you could also use a spatialization technique to limit the number of collision tests performed in each iteration of the loop. Something that looks technical said like that so I redirect you to this course which will explain it so much better than me, hoping that you are a little comfortable with C++ but it is the best course on raycasting that I have never found personally:
https://lodev.org/cgtutor/raycasting.html
You don't have to reproduce the code shown exactly, at least understand what it says and you should be able to write your own code on your own.
By the way, this site contains a lot of very useful resources for graphic programming
Edit:
NoreoAlles wrote: ↑Tue Mar 28, 2023 3:50 pm
I quickly made it render in 3d, thought you might want to see. I´ll later fix the fisheye and maybe make a full game out of this and post it here on the forums. I for now have copied your code exactly but i will ofc change it later on, hope you dont mind
Sorry I didn't see your answer, well done it's super cool! And no, it doesn't bother me at all, it's made for it, and if you improve it it's even better
If you make a real game out of it, I really advise you to see the link I gave you to optimize and reduce the number of iterations of the while loop, it will be very useful for you to do something really clean!
Re: Raycaster Issues (Horizontal Checking)
Posted: Tue Mar 28, 2023 4:27 pm
by darkfrei
Your code
Code: Select all
if self.a > math.pi*2 then
self.a = 0
end
must be
Code: Select all
if self.a > math.pi*2 then
self.a = self.a - math.pi*2
end
Maybe just this for both rotations (not tested):