Super Fast Ray Casting in Tiled Worlds using DDA

174,925
0
2021-02-28に共有
In this video I look at how the "traditional OLC" method of raycasting in various videos is in fact terrible, and look at the more intelligent DDA algorithm which can significantly (orders of magnitude) be more effective at determining ray length in tile or voxel based worlds.

Source: github.com/OneLoneCoder/Javidx9/blob/master/PixelG…
Demo: community.onelonecoder.com/members/javidx9/RayCast…
Also: lodev.org/cgtutor/raycasting.html
Patreon: www.patreon.com/javidx9

YouTube: youtube.com/javidx9
youtube.com/javidx9extra
Discord: discord.gg/WhwHUMV
Twitter: www.twitter.com/javidx9
Twitch: www.twitch.tv/javidx9
GitHub: www.github.com/onelonecoder
Homepage: www.onelonecoder.com/

コメント (21)
  • @lien3729
    that's literally THE article that i reed for learning raycasting
  • @Nayapeaks
    That's amazing! I got into computer graphics in university and at that time we didn't visualize anything and concencrated mostly on the math aspects. I spent a few weeks in my semester break and coded a few computer graphic algorithms on my own. At the beginning it was really frustrating but then I really got into it and nowdays it is one of my favorite computer science topics. I wish they had teached us that beautiful subject like you did. It's super intuitive with a little bit of drawing. Thanks man. I really appreciate your great content!
  • I figured this out by myself while making a 2D platformer for a homework, and thought that its the stupidest solution possible, but now I'm kind of proud of myself
  • @Dominexis
    I implemented this in Minecraft for my custom entity hitbox and motion system, it has allowed me to make physics-based movements for my mobs. It's really quite something.
  • @sma-mn5xe
    I don't know how to say that your tutorials are perfect. you are so patient in explaining things and I really love it. you are my hero in programming.
  • Before this, my raycaster was taking small little steps and it was SUUPER laggy. I was about to quit until I tried your method and it ran butter smooth! What a relief.
  • Thanks for the video ! I started to look into DDA ray casting and found the article you've mentioned, but couldn't understand it. So I started to reverse-engineer the RayCastWorld extension of the PGE, but my implementation wasn't working properly. You've saving me lots of headache :)
  • @peanutatomic
    Wow you helped me so much! I never really understood the DDA algorithm so I couldn't implement it into my C# raycasting engine. The way you explained it really helped and I've got it working with my engine now. The speed has improved greatly from about 11fps to 500fps. Thanks!
  • you precalculate the rise and run (you also calculate the first rise and run, as your position could be anywhere inside the square at first) you set a variable to your X coordinate (call it "A") in the loop: --you get the Y coord of the next wall up --you go right one square, and go up by the rise --if you've crossed the Y coordinate of the next wall up: ----you increment "A" by the run ----do a wall check at (X - "A", Y = the Y coord of the next wall up) --do a wall check at (X = current X pos, Y = current Y pos) do this until you've found a wall also flip some things to check other quadrants also be careful with precision because rounding errors accumulate here
  • @whoshotdk
    This speeds things up from the old "step a tiny amount" method by several orders of magnitude, I reckon. Incidentally, it's remarkably easy to replace the wall finding code from your "First Person Shooter" videos with this. I think I even have enough cycles left to repeat the raycasting process a couple more times now, - I can have different tiles/blocks rendering above (or below) the "zero" height. Also, I've tried Lode, Sage3D, Permadi and Vinibiavatti1's tutorials and while Vinibiavatti1's comes close, your tutorials are the only ones I've been able to follow and implement well and correctly. Thank You Javid! Now I'm off to make "RayCraft" (TM) 😀
  • This video has been super helpful for me in implementing block selection in my Minecraft clone. I've tried twice to adapt the method to 3D and everything tends to work except when I aim down the planes made by any two axis. This second time I checked someone else's implementation of DDA and found a comment in their code where they note that truncating the ray origin into a vector of integers will have issues in the negative axis. Turns out this was exactly the source of my issue and now after applying a component-wise flooring everything works fine.
  • I was just working on something with the PGE and I saw this pop up in my notifications. Glorious days!
  • @64jcl
    Using DDA to do longer jumps requires multiplication which is a slower operation than many adds, especially on older computers (and 8 bit computers dont even have multiplication) so adding might be just as fast as the only way to speed this up in such a CPU is by massive table lookups to do the multiplication often in a system that is low on memory. I have done a raycaster on a C64 but will look more into if I can use elements of DDA to speed it up even more, or if the multiplication tables will take too much space. But thanks for explaining the algorithm with such precision.
  • Oh neat, just 12 hrs ago I posted a video of a wolfenstein-ish renderer using this raycasting method that I ported entirely into a compute shader I'm glad you're putting this out now, the command prompt FPS was really neat but I was very dissatisfied with that raycasting method. You have a clear way of communicating and I appreciate that you code in a real language :P
  • @foxto100
    ah cool, I used this method but in 3d for voxels recently.
  • I’m just about to make a voxel raycast engine using oct-trees and sign distance functions, and was trying to think of how to do this. Thank you for the video.
  • Since we are talking about straight lines we know that they have one constant angle to the x-axis and one constant angle to the y-axis. This means that for one ray you need to compute 1/cos(theta_x) and 1/cos(theta_y) only once and those are your increments in lengths of the line when we increment x and y by 1 respectively, no square roots needed since they are expensive to compute.
  • I have been looking for this exact solution for months as an aside to a voxel project I'm working on! I even used your A* algo for it (albeit heavily modified). Thanks for making such digestible content, it really helps beginner developers such as myself understand concepts that seem just a little out of reach :)
  • Nice, this is how I learned Raycasting as a kid and subsequently programming as a whole from that project. I ended up incorporating everything I learned into that project in some way or another. Funny part is how you can manage to get this done in such a small amount of code yet in Turbo and Borland C++ the size of this project, even before I started adding a bunch of features was rather large in order to get it to run at a decent speed needing things like DMA pixel transfer, special video modes and screen buffers, Fixed point mathematics