I've been working on my first Raycaster and I ran into a problem I can't seem to fix.
I think it has to do with the CAMX variable, and the Ray Hit section of the code (Specifically CAMX's implementation in the RDIRX and RDIRY values).
Depending on the direction I'm facing I get lines that go straight through everything (With virtually no line-height).
I've also noticed that this bug tends to only happen in the reverse SIDE as the wall it's supposed to hit,
Front wall (SIDE 0) has a line that has the color of a SIDE 1 wall.
Here is how it looks:
Here's the code:
I'm soo close to getting this working nice and smoothly. Any help is appreciated, thanks!
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/12874/56_av_violet_pikuseru_flat.gif)
I noticed the gaps only appear along cardinal directions (axes) relative to the viewpoint, so I figured it was probably an over/underflow when some vector's X or Y is too close to 0.
Looking in the code, I found this:
-- length of ray from one side to another raydx = sqrt(1 + (rdiry * rdiry) / (rdirx * rdirx) ) raydy = sqrt(1 + (rdirx * rdirx) / (rdiry * rdiry) ) |
Pico-8's numbers are fixed-point 16.16, so if a value is less than 1/256 and you square it, that's less than 1/65536, which is the smallest number Pico can represent. Similar for squaring 256. Do that and, in this case, you're suddenly dividing by zero, which on Pico gives you the closest value to infinity, 32768.
Your rdirx,y values don't seem to go >= 256, but they do go < 1/256, so the optimization being used in that code will not work well without true floats. Technically it can underflow on a true float as well, but only extremely rarely.
If you expand the optimized code to what it really represents, which is the scale you want to apply to the eye ray to turn it into steps, then this is what it means to do:
-- length of ray from one side to another local rdirl=sqrt(rdirx * rdirx + rdiry * rdiry) raydx = rdirl/abs(rdirx) raydy = rdirl/abs(rdiry) |
With that, it works without gaps. Note that raydx,y are meant to be positive scales for a separate vector, so I had to use abs() to replace the implicit abs() we originally got by squaring the rdirx,y denominators when they were inside the sqrt().
I think the optimization was probably adapted from other code in which it worked better. It looks like it was designed to reduce the number of operations, though honestly I think the thread got lost somehow and the optimized code actually ended up doing more work by calling sqrt twice. So the replacement shouldn't hurt you at all. It may even be faster.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/12874/56_av_violet_pikuseru_flat.gif)
I think there may be an unrelated issue somewhere else, also related to Pico-8's precision. Sometimes if I'm basically right on a wall, I get a cluster of gaps in front of me. I'm sure this is to do with the lack of precision when stepping along rays, where your steps can't quite be represented correctly with Pico's number system because the distance between you and the wall is too tiny.
I think it's probably unavoidable, though. The solution is just to keep the camera somewhat away from walls. In general you want to avoid that kind of extremely-small-number math anyway, even with floats.
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](https://www.lexaloffle.com/bbs/files/25520/lamda.png)
Works perfectly!
Thanks for the help!
This code was adapted from the C++ raycaster which of course has more capable doubles/floats.
I noticed when debugging that I was getting some very large numbers, I just didn't think it could be from the values being negative.
I originally thought this was an issue with Pico-8's SQRT function, so I found another one, which fixed another problem, but introduced another as well.
Thanks for the well-explained answer as well!
![](/gfx/set_like0.png)
![](/gfx/top_drop.png)
![](/media/12874/56_av_violet_pikuseru_flat.gif)
I should clarify. When I said they were less than 1/256, the issue wasn't that they went negative. it was because they were between 0 and 1/256. If you square a number like that, it'll underflow to 0 on Pico.
Anyway, you're welcome. Have fun with Pico!
[Please log in to post a comment]