Hi Lydia! Thank you! I was hoping to hear someone say that. I tried to make this video fun to watch for all viewers. Those are my friends and they had many creative ideas that I really liked filming and editing. Maybe they will be in the next sponsor video too. :)
@@3DSage water has recently released a new type of water called sparkling water so they might want you to promote that. Sparkling water is like normal water but it sparkles which is pretty insane
That water commercial exactly emulates the style of a modern generic commercial. Got that super out of focus lens flare stock footage blended using soft light. Even snuck in a lens flare transition 🤣 beautiful
Man, idk if you are going to read this, but really thanks, I was trying to create a raycaster for a very long time and i finally created a functional one with the help of your video
ngl i appreciate you not slowing the video down to show the code step by step but rather explained what you were doing right along with it. Makes it so you can work at your own pace if you choose to follow along and i respect that.
I love games but I know nothing about games engines. This vid was recommended to me by a couple of guys who work in the games industry. I watched this and found it simply fascinating. I was like "That's it? THat's a game engine?" but I was also like "That is so brilliant." Thank you for such a good explanation of how this works.
pro tip for anybody following this tutorial: don't just copy the code, attempt to understand why each math thing needs to be there and how it contributes. you actually learn what's happening and you feel a lot smarter by the end
I have to assume that when trigonometry started to roll I just copied and pasted. But otherwise makes sense. Also, I'm building with SDL, not OpenGL, so copy and paste is not an option. And I'm using variables that make sense, not Rx, ry, MX...
We totally need the 2nd part of this tutorial, It's the best raycasting tutorial I could find, and it would be super cool to have all the features you mentioned, keep up with the great work!
I don't mean to sound like a heathen but I was actually following this tutorial using Visual Studio and SFML. Your instructions were still clear enough to get a good idea of what to do. Thank you immensely. This is a great tutorial.
In one sentence you're explaining to people that sin/cos take radians and what the value of 2PI is, in the next its negative tan inverse with bitshifts and epsilons, great, right there with you.
Just finished making this in javascript and Html5, had to workaround some issues but it was two (long) days of fun. Thanks for making amazing videos that push people forward!
I love this series but it would be a little easier to follow the code if the variable names were just a little bit more descriptive. I know short variable names are more convenient but when we end up dealing with a bunch of variables named px, py, ry, rx, mp, my, mx, ra, pa etc. it's a bit tough leaving mental notes what each one was short for.
Interestingly ray-casting is actually pretty darn inefficient, even on a 286 in 1992. John Carmack's foreword for Fabien Sanglard's book mentions this - how a Doom style raster engine would have been more efficient (hence Wolf3D on SNES uses a BSP tree raster engine, rather than ray-casting). For your GBA tutorial if you want to avoid devkitPro I'm actually currently writing a new CMake based toolchain that uses ARM's GNU embedded toolchain - complete with debugging in Visual Studio + mGBA and compatible with any CMake IDE. Might be a lot simpler than asking people to install devkitARM.
Hi there! That is interesting. Raycaster's are pretty fast when compared to other techniques. I have looked into BSP trees but they have some limitations too. Maybe I can make that video too. I'll have to check out that book. I'm glad you are making your own and I look forward to your videos!
@@3DSage The problem is that while raycasting is simple, it requires many redundant raycasts for most visible walls, so it doesn't take into account spatial locality (i.e. if a screen pixel 1 is covered by wall A, other screen pixels near by are likely to also be covered by wall A). Doom finds the list of all potentially visible walls up-front (up to 256 walls, I think), and handles occlusion on a per-wall basis, rather than per-screen-column. This is how it was able to support much greater geometric complexity.
@@Ehal256 You are wrong. He is using a grid and does not check all available walls. What you mean is a polygon-based Raycaster, everything you said is only true for Polygon (Triangle) Raycasters. If you want to check all triangles in space with raycasting, you have to loop through them. In his specific case, there isn't a single triangle on the screen, it's basically a 2D game on a grid, he only checks the grid-tiles he needs to check, there is almost no redumdant check in his implementation - but he can't add height to his levels (or it would be very very difficult). (Doom had height in its levels (ramps, stairs, elevators))
Thanks for the excellent explanation! I made a raycaster 30 years ago as a sample project to teach myself x86 assembly. The one part that I never got around to fixing was the fish eye effect. Turns out it's just a projection onto a plane perpendicular to the view vector, but I didn't know that at the time.
Thank you for sharing that! I'm impressed you did it with assembly. And yup, a simple cosine multiplication can correct the fish eye effect. Raycasters are a great program to make so I had to make this video to share it with people.
This was a very excellent video for an introduction to rudimentary 3D graphics for programmers! After 4 hours of refactoring the code in Java using the standard graphics library and digesting the math, I was finally able to do everything in the video! When I finish the other tutorials, practice it, and finish my own game, I'll be sure to tag you and give you all the praise in the world. I can't thank you enough. No video details this early technique in Java on UA-cam, so I'm glad that your code is so easy to transport over to Java!
thanks so much for making this video. i have been trying for an EXTREMELY long time to find out how to get rid of that dang fish eye effect. I was doing all of this the naive way also, so you are really helping me optimize it.
This tutorial is amazing, I wanted to make a 3d game in pygame, i got all the way to ray casting, but 3d rendering seemed so complicated. Then after hearing that its just rectangles, I attempted to make it all, and it worked firat time, and i exploded in happiness. Gonna learn some more soon. Thanks alot for this
Ever since it came out, I was curious about how they made this game. I learned C at school at the end of the 90's and still it wasn't clear to me. This video finally tell me the truth, after all those years. Thank!
This is a great tutorial. I implemented it along in Java. So a 17 minute video took more than an hour to get through. I had some problems, though. For example, when running before certain parts were implemented I would get errors that you didn't show getting. In particular there was an index out of bounds error for an array, on the line that used map[mp]. You would later in the video add the condition mp>0 to remove that error. I anticipated that. But it might suck for people implementing along to see that much later, rather than earlier. My final product came out pretty good, but it's a little glitchy. Sometimes I have most rays properly coming out of the 60 degree line of sight, but a few rays coming out of the back of the character's head, in the other direction. I don't yet know what accounts for this. Maybe if I copy and paste your Github source code and then convert it to Java, it will correct whatever error there is. Maybe it is a typo, as I made a few of those already. But the previous typos were easy for me to diagnose and fix. This one seems more confusing to me. I also wonder if your part 2 video won't just correct this automatically, if I am loading a texture rather than drawing a line. But I suspect that the error will remain for as long as any rays are being cast backwards. One part that I thought might cause the problem is... You have two ifs, one which checks a less then, and one that checks a greater then. But this ignores the case where the lines are equal. I had originally coded it with an else rather than two ifs, but I changed it to two ifs thinking that might fix the problem, but it didn't. Hmm... Now that I think of it, maybe this could be the cause of the backward ray cast. If the first if sets the ray correctly... No wait, that doesn't make sense. Hmm... Checking your Github source now, you only have 1 if where you had 2 ifs in the video. The two ifs compared disH and disV. But you only have one condition for that in your Github source, and you set one to be the other if it's longer. I wonder if that'll correct my backwards casting rays. Edit: Yep, that fixed the backward casting rays. But I still have rays traveling through walls sometimes. Weird. I bet if I just copied and pasted your Github source and converted it to Java it'll work. Edit: Translating from your Github source fixed the problems.
Min sharing it? I’m trying to do it on javafx but I’m stuck on casting the lines from the center of the rectangle and getting them to move along with it. It would mean a lot
wow... you make it sound simple... i feel like i could do it with the minute little programming knowledge i may have with just a bit more effort... and tutorials.
As someone with no programming experience what so ever I left this video both more knowledgeable and more confused. While I don't understand some of the things you're saying I do not understand some of the basic ideas that go in to this. So thank you for educating me. I now know that I know more. And also know a lot of what I don't know.
Very nicely done video. Love your sense of humor! I found it interesting that your player point, the single dot was square, while mine was round. I added the following code so you can use the cursor keys instead of WSAD.. (or as well as WSAD)... First add the following function... void processSpecialKeys(int key, int x, int y) { switch(key) { case GLUT_KEY_LEFT : pa -= 0.1; if(pa < 0) pa += 2 * PI; pdx = cos(pa) * 5; pdy = sin(pa) * 5; break; case GLUT_KEY_RIGHT : pa += 0.1; if(pa > 2 * PI) pa -= 2 * PI; pdx = cos(pa) * 5; pdy = sin(pa) * 5; break; case GLUT_KEY_UP : px += pdx; py += pdy; break; case GLUT_KEY_DOWN : px -= pdx; py -= pdy; break; } glutPostRedisplay(); } Then in main() add: glutSpecialFunc(processSpecialKeys); right after the glutKeyboardFunc() call. GLUT uses a separate function to handle special keys. You can use GLUT_KEY_F1 to use F1 for example etc. Also note that you do not need {} after an if() if you only have one command line to execute. You only need {} braces if you have more than one line to execute for that if().
The only problem with this is that walls can only be in certain places. I made one were the rays just detect with the walls them selfs. (With a loop the find the collision with each wall and finishes on the closest distance) My method is much more efficient for scenes that are big or have walls in any direction. However, for like a big tightly cramped maze, yours would be better. (more walls, less space, straight walls) But I could add in chunking and then there would be almost no situations where mine is worse. My method requires more math, however. How it does it is that it to the ray into a y=mx+b equation with a starting point and each wall into a y=mx+b with two endpoints. Then it performs solving a linear equation of the two to find the intersection point. It makes sure it is valid (correct side of the placer and not above or below the wall). Then finally it calculates the distance to the point. Does this to all the walls then it will find the smallest distance and that is the final distance the ray has traveled. There are also more optimizations that could be done to both yours and I did to mine, in which you only shoot out certain rays in the direction that you need to (this a good description of it ncase.me/sight-and-light/ ). One last thing: whenever I said my method, I do not mean I am the very first to use it or am I trying to talk about how mine is so much better than everything else, it is just that I could not find a better way to say it.
Your name doesn't lie, amazing video! Can't wait for part 2 PS: There is a but... don't like the sponsor, water is such a useless product, i can live perfectly without it...
WOW! I went ahead and tried your sponsor water, and it CHANGED MY LIFE!!! I don't know how I survived without it before. THANK YOU 3D SAGE (also, great video)
C really isn't that complicated at all. The only things to be aware of is the need to manage memory. Otherwise you can end up with memory leaks which can ruin your day. These are pretty easy to avoid unless you're doing complicated programs though.
i have a python background, and raycasting has always been interesting to me, but felt like it was too complicated, even though I don't understand a lick of the code, you made the math and concepts way to easy to understand! You are a fool for giving me this power
Can someone explain a bit more about -1/tan(ra) at 7:02. What does the negative inverse of tangent do exactly and what happens when you multiply (py-ry) by the negative inverse of tangent. Sorry if this is a simple concept I'm just trying to understand a bit more :)
This was the fundamental piece missing from this video for me. I struggle with the math. Drawing it and revisiting the trig functions helped me. I also think arctan is incorrect and 1/tan(ray_angle) is actually the cotangent(ray_angle)? If you think of cot and tan as ratios and how all the trig functions relate to the unit circle, the multiplications start to make sense because the values cancel out. 1. (player_y - ray_y) aka: the Y coordinate is the sin(ray_angle) of the triangle you're trying to solve. 2. cot can be expressed as cos/sin 3. sin * cos/sin, the sin cancel out and you're left with cos, which is the ray_x you're looking for, but in the context of your ray angle. The player_x needs to be added so the ray_X point is offset the correct amount of pixels. Use this same approach with the vertical intersections to understand which tan (aka sin/cos) is used instead.
This was great. Educational and fun. Inspired me to develop my own raycaster based on the tutorial. I had already dabbled in this space in my university years so this is right up my alley :) Thank you very much. Also love the tongue in cheek nature of the video.
Hey I am having lots of trouble with the code crashing when i am at the point that I have to scan for lines. Could you please send me a link to the source so I can check what I am doing wrong
Hit us with that second part please! Also, could you highlight the changes you make as you make them? You've really come a far way since your first few tutorials but I find that for some people, who would be total beginners, they could miss some of the quicker changes you make! Keep up the great work man! :)
For those using Ubuntu, compile in the terminal like this: g++ original_file_name.cpp -o file_rename -lGL -lGLU -lglut and then just: ./file_rename Luck!
Love this! I don't fully understand all the math yet :P looks like there is a small mistake around 8:33 with your second typecast on line 70 though. :)
Fantastic! This is very straight-forward, I got it all to work in Godot. Except fixing the fish-eye effect, it works vertically, but horizontally it's going insane
@@3DSage Sounds great, would love to start programming my own GBA games. Can we expect downloads for Minecraft & Zelda too (even if they are in early stages/are unfinished at the moment)?
I do like how you write methods but without comments and more denser math it is impossible to dissect what is doing what without several rewatches. It's not a good syntax for tutorials.
Where’d you get the “code.cpp” file at the start? And when I typed it out myself and compiled and ran it opens “glut.h” and says (in the compiler tab at the bottom) “483 c:\program files (x86)\dev-cpp\mingw32\include\GL\glut.h undefined reference to `_glutInitWithExit@12’ “ what does this mean and how do I fix this? I know I’m late but i really want this to work! Thanks in advance! EDIT: I fixed it by adding a ‘#define GLUT_DISABLE_ALTEXIT_HACK’ but now it has a red bar on line 7 (now 8) and an error saying “undefined reference to `_imp_glClear@4’” I’ll try to fix it on my own... I’ll update if I fix it and more errors pop up! Guess this comment is my journal now!
Thanks for making this AWESOME tutorial video! I started up with a little bit of UE4 and Python knowledge but after watching this with visual studio open for 6 hours, I think I get it and even implemented fun stuffs like coloured blocks (as shown in the video) and jumping. This friendly and interesting tutorial even pushed me to start studying C/C++! Hope to see more good stuffs like this one in the future.
@@pointers2010 It's annoying to read, even if you know how to program. Formatting code properly just saves everyone lots of mental capacity understanding it. Good luck making sense of that code without watching it being written, I guarantee you waste a few minutes every segment.
I still haven't figured out how to do this exactly your way, but I finally figured out how you did this. Basically, each line is directed at the cubes, and the main camera visualizes each of those lines as, well, lines. Except, the lines visualized by the camera are thick enough to hide the fact that you aren't using the limit of lines to process the rendering, making them blocky at the top and bottom. Regardless, these lines visualized by the camera change height by the distance of the ray pointed at one of the walls. So, now I know that you could also do this on the z axis. By adding more rays on the z axis and changing the lines to be more like blocks, the new "blocks" can change height on a z axis and change width too(if you make the rays have semi-rays in-between) If you didn't make this video, I wouldn't have figured this out, thanks!
I have been making video games in Unity as an amateur hobby game developer for several years, on and off. This looks so epic and cool that I feel inspired to dare dip my toes into pure code based game design and maybe create my own little 2D block-based level platformer engine. Just for fun!
Thank you so much. Raycaster for dungeons and mode seven for the overworld work so well on a tiny indi project to break out of the 2d and isometric mold.
yay, i did it! used SDL2 for graphics... had to work out some quirks in the initial version (mp >= 0 !!!) Thanks for this great tutorial! It got me motivated to give it a try finally
I just found you today and you like my favorite person already. I’ve also never heard someone else who does the S whistle with their teeth and tongue when saying some words. I’ve been messing with OpenGL and Vulcan the past few months and you are awesome
you are better than university professors. You teach in an easy to understand method. My only suggestion would be is to have popup links to other videos at certain parts to explain certain things in more detail if people who are learning this want to have a better understanding of things such as the sin or cos or what a tangent is and ect.
I don't know anything about video games but it is really neat to see how the programming is done. Love your water sponsor 🤣
Hi Lydia! Thank you! I was hoping to hear someone say that. I tried to make this video fun to watch for all viewers. Those are my friends and they had many creative ideas that I really liked filming and editing. Maybe they will be in the next sponsor video too. :)
3DSage I demand a line of purified water be made that has that label.
@@kris_0520 I would like to see that too! :)
@@3DSage water has recently released a new type of water called sparkling water so they might want you to promote that. Sparkling water is like normal water but it sparkles which is pretty insane
@@iamarchibald It also kinda tastes like TV static, which I didn't even know had a taste
I can't find the *WATER* link
Hahahahhahahahahha waaaaaaat theeeeeeeeeeeee fuuuuuuuuuuuuuuuccccccccc
water.com
Thanks, Whumchy!
@@shiiiguthewise6778 no referrers
link for discount tho awww
C4NN0n use code H20 when buying for discount
That water commercial exactly emulates the style of a modern generic commercial. Got that super out of focus lens flare stock footage blended using soft light. Even snuck in a lens flare transition 🤣 beautiful
Man, idk if you are going to read this, but really thanks, I was trying to create a raycaster for a very long time and i finally created a functional one with the help of your video
I'm very happy to hear that! I'm so glad I could help. And thank you for the nice comment.
Really makes me want to pick up C and start coding. Please do make a part 2, your explanations are clear and to the point
Raycasting seems really complicated. But this video really makes it seem way less scary!
That was my goal! I wanted to take it step by step so it's easier to understand the concept. :)
Its probly how our brains see the world lol
I'm a ICT student,this is medium hard,maybe....oof😐
its really simple its just to do it it requires a shit ton of complex maths
For someone like me, it easy! I’m doing it lower level than OGL, rather X11 (Linux-only)
Not only is this very digestible educational information, it's also hilarious! Thanks for this content.
That's what I was hoping someone would so so thank you for the very nice comment! :)
ngl i appreciate you not slowing the video down to show the code step by step but rather explained what you were doing right along with it. Makes it so you can work at your own pace if you choose to follow along and i respect that.
His voice really matches the cat so well
I love games but I know nothing about games engines. This vid was recommended to me by a couple of guys who work in the games industry. I watched this and found it simply fascinating. I was like "That's it? THat's a game engine?" but I was also like "That is so brilliant." Thank you for such a good explanation of how this works.
pro tip for anybody following this tutorial: don't just copy the code, attempt to understand why each math thing needs to be there and how it contributes. you actually learn what's happening and you feel a lot smarter by the end
I feel like this would be easier if his variable names were longer then 2 characters
Maybe it would be more helpful if his code actually compiled
@@elllieeeeeeeeeeeeeeeeeeeeeeeee compile deez nuts
That's right. Which is what this video failed to do.
I have to assume that when trigonometry started to roll I just copied and pasted. But otherwise makes sense. Also, I'm building with SDL, not OpenGL, so copy and paste is not an option.
And I'm using variables that make sense, not Rx, ry, MX...
We totally need the 2nd part of this tutorial, It's the best raycasting tutorial I could find, and it would be super cool to have all the features you mentioned, keep up with the great work!
Damn dude, this is some quality content
Thank you! I'm happy to hear that :)
@@3DSage been 4 years now and your water sponsorship still cracked me up, good stuff man 👍🏻
quality water
I don't mean to sound like a heathen but I was actually following this tutorial using Visual Studio and SFML. Your instructions were still clear enough to get a good idea of what to do.
Thank you immensely. This is a great tutorial.
Hi 3dsage! I'm a bit confused as to where to find the link to your sponsor.
@Austin Entenmann Thanks!
@Austin Entenmann Took me 2 minutes to load that site
@Austin Entenmann Cool, thanks! Ima buy Water tm right now
In one sentence you're explaining to people that sin/cos take radians and what the value of 2PI is, in the next its negative tan inverse with bitshifts and epsilons, great, right there with you.
The dislike is from Unity
i use unity but didnt disliked
Lol
You don’t like unity so you made your own raycaster?
Yknow there is like hundreds of game engines at are very different from unity
@@Coolae450r/wooooosh
I dont think I could live if you didn't show me the sponsor. Thanks, singlehandedly saved my life!
Not all heroes wear capes. Some have bottled water :)
Just finished making this in javascript and Html5, had to workaround some issues but it was two (long) days of fun.
Thanks for making amazing videos that push people forward!
I've been working on the same thing in javascript too! I know this comment is 3 years old, but would you be willing to share your source code?
even though I am 4 years late. Will you share the source code with me please?
Your sponsor literally keeps me alive. Thanks sponsor.
I love this series but it would be a little easier to follow the code if the variable names were just a little bit more descriptive. I know short variable names are more convenient but when we end up dealing with a bunch of variables named px, py, ry, rx, mp, my, mx, ra, pa etc. it's a bit tough leaving mental notes what each one was short for.
yes I was having a hard time so I used chat gpt to help me and explain some of it, it worked surprisingly well
@@jackmarquette1351 Ugh.
@@mariocamspam72 it's the exact same as being helped by a youtube video lmao
@@mariocamspam72 hurr hurr ai bad
Comment: this works to remember You what's do the program that you're programing and do not use mental notes 😅
the "So.. Just hang in there" is so motivating, tysm
Small steps and just keep going! You can do it!
Interestingly ray-casting is actually pretty darn inefficient, even on a 286 in 1992. John Carmack's foreword for Fabien Sanglard's book mentions this - how a Doom style raster engine would have been more efficient (hence Wolf3D on SNES uses a BSP tree raster engine, rather than ray-casting).
For your GBA tutorial if you want to avoid devkitPro I'm actually currently writing a new CMake based toolchain that uses ARM's GNU embedded toolchain - complete with debugging in Visual Studio + mGBA and compatible with any CMake IDE. Might be a lot simpler than asking people to install devkitARM.
Hi there! That is interesting. Raycaster's are pretty fast when compared to other techniques. I have looked into BSP trees but they have some limitations too. Maybe I can make that video too. I'll have to check out that book. I'm glad you are making your own and I look forward to your videos!
@@3DSage The problem is that while raycasting is simple, it requires many redundant raycasts for most visible walls, so it doesn't take into account spatial locality (i.e. if a screen pixel 1 is covered by wall A, other screen pixels near by are likely to also be covered by wall A). Doom finds the list of all potentially visible walls up-front (up to 256 walls, I think), and handles occlusion on a per-wall basis, rather than per-screen-column. This is how it was able to support much greater geometric complexity.
It's may be inefficient but it's so simple to make (but realy long) that you can run a 3D maze in a game like geometry dash using this technique
@@Ehal256 You are wrong. He is using a grid and does not check all available walls.
What you mean is a polygon-based Raycaster, everything you said is only true for Polygon (Triangle) Raycasters.
If you want to check all triangles in space with raycasting, you have to loop through them.
In his specific case, there isn't a single triangle on the screen, it's basically a 2D game on a grid, he only checks the grid-tiles he needs to check, there is almost no redumdant check in his implementation - but he can't add height to his levels (or it would be very very difficult).
(Doom had height in its levels (ramps, stairs, elevators))
@@3DSage I would love to see a video about bsp trees, it would really help me understand how they work a little bit better.
Thanks for the excellent explanation! I made a raycaster 30 years ago as a sample project to teach myself x86 assembly. The one part that I never got around to fixing was the fish eye effect. Turns out it's just a projection onto a plane perpendicular to the view vector, but I didn't know that at the time.
Thank you for sharing that! I'm impressed you did it with assembly. And yup, a simple cosine multiplication can correct the fish eye effect. Raycasters are a great program to make so I had to make this video to share it with people.
part 2 ? when when ? make a full series !
Yes
part 2? when when? make a full series!*
Yes
I really want at least a part 2
He did a one now, you can check it!
This was a very excellent video for an introduction to rudimentary 3D graphics for programmers! After 4 hours of refactoring the code in Java using the standard graphics library and digesting the math, I was finally able to do everything in the video! When I finish the other tutorials, practice it, and finish my own game, I'll be sure to tag you and give you all the praise in the world. I can't thank you enough. No video details this early technique in Java on UA-cam, so I'm glad that your code is so easy to transport over to Java!
Nice video. :) Made one back in 1986 on an Amiga 1000, assembly instead of C/C++.
Hey that's really cool and very impressive! :)
Are you still programming? I was -10 years old back then.
I sure love your sponsor. I couldn't live without them!
really engaging tutorial though
thanks so much for making this video. i have been trying for an EXTREMELY long time to find out how to get rid of that dang fish eye effect. I was doing all of this the naive way also, so you are really helping me optimize it.
Now I want to make one myself but maybe in JavaScript or something like that to try how far I could push the idea
Absolutely, you can since this is easy to port between languages. If you post it, send me a link! :)
@@3DSage tempting to try porting it to python.
@@Trekeyus me too, but I got stuck at 9:30 how far are you?
@@suptnt2004 I'm porting it to GML... stuck at the same spot
@@suptnt2004 stuck getting motivation to even start keep putting it on the back burner
This tutorial is amazing, I wanted to make a 3d game in pygame, i got all the way to ray casting, but 3d rendering seemed so complicated. Then after hearing that its just rectangles, I attempted to make it all, and it worked firat time, and i exploded in happiness. Gonna learn some more soon. Thanks alot for this
I really appreciate your efforts into explaining coding in a way anyone can understand!
This was the first advertisement I enjoyed more than LucidChart. Well done, sir.
Can’t wait for the part 2!
Also, I can’t understand how such a UA-cam like you still do not have 500000 subscribers, you really deserve more!
everybody wants to be you... but they cant be you... so you just be you! thanks man! thanks for the love!
I've been looking for an explanation on raycasters for years, this is great! Thank you very much, please do a part 2
Ever since it came out, I was curious about how they made this game. I learned C at school at the end of the 90's and still it wasn't clear to me. This video finally tell me the truth, after all those years. Thank!
13:46 "And by we, I mean... Umm... Leo."
I feel attacked.
Damn it, Leo, you had one job
Me too.
@@leobozkir5425 Hello Leo, I'm Leo. Nice to meet you.
@@ljreinworth hello again :D
@@geko2867 hey there again, Rako! You're not intentionally looking for my comments are you? It's been a while, how are you?
I am in the process of writing my own game engine in DirectX and I stumbled upon this video. This is super useful for me! Thank you!
I'm glad to hear that! I hope you post your game engine when you get it working. I hope to see it!
This is a great tutorial. I implemented it along in Java. So a 17 minute video took more than an hour to get through. I had some problems, though. For example, when running before certain parts were implemented I would get errors that you didn't show getting. In particular there was an index out of bounds error for an array, on the line that used map[mp]. You would later in the video add the condition mp>0 to remove that error. I anticipated that. But it might suck for people implementing along to see that much later, rather than earlier. My final product came out pretty good, but it's a little glitchy. Sometimes I have most rays properly coming out of the 60 degree line of sight, but a few rays coming out of the back of the character's head, in the other direction. I don't yet know what accounts for this. Maybe if I copy and paste your Github source code and then convert it to Java, it will correct whatever error there is. Maybe it is a typo, as I made a few of those already. But the previous typos were easy for me to diagnose and fix. This one seems more confusing to me. I also wonder if your part 2 video won't just correct this automatically, if I am loading a texture rather than drawing a line. But I suspect that the error will remain for as long as any rays are being cast backwards.
One part that I thought might cause the problem is... You have two ifs, one which checks a less then, and one that checks a greater then. But this ignores the case where the lines are equal. I had originally coded it with an else rather than two ifs, but I changed it to two ifs thinking that might fix the problem, but it didn't. Hmm... Now that I think of it, maybe this could be the cause of the backward ray cast. If the first if sets the ray correctly... No wait, that doesn't make sense. Hmm... Checking your Github source now, you only have 1 if where you had 2 ifs in the video. The two ifs compared disH and disV. But you only have one condition for that in your Github source, and you set one to be the other if it's longer. I wonder if that'll correct my backwards casting rays.
Edit: Yep, that fixed the backward casting rays. But I still have rays traveling through walls sometimes. Weird. I bet if I just copied and pasted your Github source and converted it to Java it'll work.
Edit: Translating from your Github source fixed the problems.
thanks this helped me fix the backwards casting issue
@@AwesomePowerCat :)
Min sharing it? I’m trying to do it on javafx but I’m stuck on casting the lines from the center of the rectangle and getting them to move along with it. It would mean a lot
Oh 😂 I tuned out for the ad and had to back it up. Suddenly I was like, wait, what was that sponsor?
wow... you make it sound simple... i feel like i could do it with the minute little programming knowledge i may have with just a bit more effort... and tutorials.
Yes! I was hoping to inspire anyone to make this. It's so rewarding when it works and you can edit your own levels. Please do give it a try! :)
Hey ur the guy that wanted minecraft on GBA
Lol.
As someone with no programming experience what so ever I left this video both more knowledgeable and more confused. While I don't understand some of the things you're saying I do not understand some of the basic ideas that go in to this.
So thank you for educating me. I now know that I know more. And also know a lot of what I don't know.
This cleared something up for me, so thanks ☺
That's what I wanted to hear so thank you for your comment! :)
Very nicely done video. Love your sense of humor!
I found it interesting that your player point, the single dot was square, while mine was round.
I added the following code so you can use the cursor keys instead of WSAD.. (or as well as WSAD)...
First add the following function...
void processSpecialKeys(int key, int x, int y)
{
switch(key) {
case GLUT_KEY_LEFT :
pa -= 0.1;
if(pa < 0) pa += 2 * PI;
pdx = cos(pa) * 5;
pdy = sin(pa) * 5;
break;
case GLUT_KEY_RIGHT :
pa += 0.1;
if(pa > 2 * PI) pa -= 2 * PI;
pdx = cos(pa) * 5;
pdy = sin(pa) * 5;
break;
case GLUT_KEY_UP :
px += pdx;
py += pdy;
break;
case GLUT_KEY_DOWN :
px -= pdx;
py -= pdy;
break;
}
glutPostRedisplay();
}
Then in main() add: glutSpecialFunc(processSpecialKeys); right after the glutKeyboardFunc() call. GLUT uses a separate function to handle special keys. You can use GLUT_KEY_F1 to use F1 for example etc. Also note that you do not need {} after an if() if you only have one command line to execute. You only need {} braces if you have more than one line to execute for that if().
The real new interesting thing invented by ID was the sectors, if I'm not mistaken.
Thats right but in my opinion build engine is better 😊
Gosh a part 2 would be amazing. I've already watched this video at least 20 times and used it to code a ray-casting engine.
The only problem with this is that walls can only be in certain places. I made one were the rays just detect with the walls them selfs. (With a loop the find the collision with each wall and finishes on the closest distance) My method is much more efficient for scenes that are big or have walls in any direction.
However, for like a big tightly cramped maze, yours would be better. (more walls, less space, straight walls) But I could add in chunking and then there would be almost no situations where mine is worse. My method requires more math, however.
How it does it is that it to the ray into a y=mx+b equation with a starting point and each wall into a y=mx+b with two endpoints. Then it performs solving a linear equation of the two to find the intersection point. It makes sure it is valid (correct side of the placer and not above or below the wall). Then finally it calculates the distance to the point. Does this to all the walls then it will find the smallest distance and that is the final distance the ray has traveled.
There are also more optimizations that could be done to both yours and I did to mine, in which you only shoot out certain rays in the direction that you need to (this a good description of it ncase.me/sight-and-light/ ).
One last thing: whenever I said my method, I do not mean I am the very first to use it or am I trying to talk about how mine is so much better than everything else, it is just that I could not find a better way to say it.
Finally a good raycasting explanation that I can actually follow along. Im using your video for creating a raycasting game on pygame. Thank you!
This is very well made! Great job sir!
Thank you for the nice comment!! :)
Finally, a good video by a good youtuber that isn't sponsored by Raid.
Your name doesn't lie, amazing video! Can't wait for part 2
PS: There is a but... don't like the sponsor, water is such a useless product, i can live perfectly without it...
Thank you for saying that! And good for you. You must be an alien. Welcome to Earth. :)
the water sponsor was just pure gold
your sponsor “water” convinced me to go down at 3am and drink “water”
*w a t e r*
WOW! I went ahead and tried your sponsor water, and it CHANGED MY LIFE!!! I don't know how I survived without it before. THANK YOU 3D SAGE (also, great video)
Interesting, as a high-level programmer, I always thought C was much harder to understand!
C is as hard as you make it out to be. You can write complex programs with simple code.
C really isn't that complicated at all. The only things to be aware of is the need to manage memory. Otherwise you can end up with memory leaks which can ruin your day. These are pretty easy to avoid unless you're doing complicated programs though.
i have a python background, and raycasting has always been interesting to me, but felt like it was too complicated, even though I don't understand a lick of the code, you made the math and concepts way to easy to understand! You are a fool for giving me this power
Can someone explain a bit more about -1/tan(ra) at 7:02. What does the negative inverse of tangent do exactly and what happens when you multiply (py-ry) by the negative inverse of tangent.
Sorry if this is a simple concept I'm just trying to understand a bit more :)
This was the fundamental piece missing from this video for me. I struggle with the math. Drawing it and revisiting the trig functions helped me. I also think arctan is incorrect and 1/tan(ray_angle) is actually the cotangent(ray_angle)? If you think of cot and tan as ratios and how all the trig functions relate to the unit circle, the multiplications start to make sense because the values cancel out.
1. (player_y - ray_y) aka: the Y coordinate is the sin(ray_angle) of the triangle you're trying to solve.
2. cot can be expressed as cos/sin
3. sin * cos/sin, the sin cancel out and you're left with cos, which is the ray_x you're looking for, but in the context of your ray angle. The player_x needs to be added so the ray_X point is offset the correct amount of pixels.
Use this same approach with the vertical intersections to understand which tan (aka sin/cos) is used instead.
He fixed the negative at the code he uploaded to Github
Loved the 'Sponsored by Water' ad, very funny.
What the hell where is the promotional code for the water! This is clickbait!
Disliked, unsubbed.
Wow. It's the first tutorial about raycasting i see, that doesn't just add sin and cos with small amount to cast a ray!
Can i get a coupon code for my water?
Waiting on that sponsorship check to come in ;)
This was great. Educational and fun. Inspired me to develop my own raycaster based on the tutorial. I had already dabbled in this space in my university years so this is right up my alley :) Thank you very much. Also love the tongue in cheek nature of the video.
Thank you for saying that! I'm working on part 4 with level editor right now :)
@@3DSage looking forward to it.
Hey I am having lots of trouble with the code crashing when i am at the point that I have to scan for lines. Could you please send me a link to the source so I can check what I am doing wrong
Hit us with that second part please! Also, could you highlight the changes you make as you make them? You've really come a far way since your first few tutorials but I find that for some people, who would be total beginners, they could miss some of the quicker changes you make! Keep up the great work man! :)
For those using Ubuntu, compile in the terminal like this:
g++ original_file_name.cpp -o file_rename -lGL -lGLU -lglut
and then just:
./file_rename
Luck!
Thank you for letting people know! :)
Been relying on Unity too much, kind of forgot how to write game from scratch, thanks for reminding the good old day
Love this! I don't fully understand all the math yet :P looks like there is a small mistake around 8:33 with your second typecast on line 70 though. :)
haha I thought I was the only one that didn't get all the math, I'm talking about his dda algorithm
ove never been so disturbingly unnerved by an advertisement for water. amazing.
can you please give me a link to the complete source code?, my code isn't working and I want to see if I can fix it.
same here bud
same
Fantastic! This is very straight-forward, I got it all to work in Godot. Except fixing the fish-eye effect, it works vertically, but horizontally it's going insane
Please do a part 2!!!!!
Ok I will :)
@@3DSage That part 2 seems to take a while to make
please make a part 2 that is everything I want in a part 2 video about this stuff. Such a good video I love it.
Download to the GBA raycaster?
I'll upload that somewhere for you to download soon. And in the next video i'll teach you how to program a GBA game. :)
@@3DSage Sounds great, would love to start programming my own GBA games. Can we expect downloads for Minecraft & Zelda too (even if they are in early stages/are unfinished at the moment)?
Just wanted to say thank you for making this. I've just used it for a project I'm working on and it helped immensely.
When I compile at 9:19, the ray doesn't show up.
make sure you check that the ray only collides with white wall
make sure you call drawRays2D() in your display function
Change the drawRays3D to drawRays2D and add drawRays2D(); under drawMap2D();. I hope this helped. 😉
I am to
@@chxry9670 I did then the ray pointed backwards and it crashed.
Earned another sub well deserved sub!Amazing tutorial and explainations.
Thank you for the support!
I do like how you write methods but without comments and more denser math it is impossible to dissect what is doing what without several rewatches. It's not a good syntax for tutorials.
That water sponsor was incredible
My friends are the best and we all had so much fun acting in the video! :)
@@3DSagehonestly it was such a well shot video I didn't realize it was home made at first lol
Also the tutorial is awesome, I've been really interested in CS and how the 90s 3d games worked and it's inspiring me to create my own!
hey, im having issues with creating the rays. is there a discord i could join for someone to help me out?
same
I have recreated your Raycaster in BBC basic for windows...it was a fun and challenging project as this was my first attempt at a raycaster.
Where’d you get the “code.cpp” file at the start? And when I typed it out myself and compiled and ran it opens “glut.h” and says (in the compiler tab at the bottom) “483 c:\program files (x86)\dev-cpp\mingw32\include\GL\glut.h undefined reference to `_glutInitWithExit@12’ “ what does this mean and how do I fix this? I know I’m late but i really want this to work!
Thanks in advance!
EDIT: I fixed it by adding a ‘#define GLUT_DISABLE_ALTEXIT_HACK’ but now it has a red bar on line 7 (now 8) and an error saying “undefined reference to `_imp_glClear@4’” I’ll try to fix it on my own... I’ll update if I fix it and more errors pop up! Guess this comment is my journal now!
No idea if you're still facing this error, but you need to link with the opengl libraries
Thanks for making this AWESOME tutorial video! I started up with a little bit of UE4 and Python knowledge but after watching this with visual studio open for 6 hours, I think I get it and even implemented fun stuffs like coloured blocks (as shown in the video) and jumping. This friendly and interesting tutorial even pushed me to start studying C/C++! Hope to see more good stuffs like this one in the future.
You implemented jumpin in a technic of raycasting? How and how does it look like?
@@plrc4593 maybe simply through shifting the displayed lines up and down with respect to the window
please, name variables properly, this is very bad practice to name variable like pxa, pv, uip etc.
Dude. You clearly don't know standard notation in programming. Naming a variable for the player x position px is standard.
We need more parts to this... show us textures and enemies! (great video, love the efficiency of raycasters)
all in part 2 :)
@@3DSage When is part 2 :(
You really need a coding style dude, the code is almost unreadable :/
What do you mean, like five statements all in one line, all using combinations of unexplained two-letter variables isn't a style?!
@@tdif3197 I feel right at home reading his code. Stop crying, guys.
that code is actually really clean for a fast video, if you dont know how to program, then it would be very hard for you to read it :/
@@pointers2010 It's annoying to read, even if you know how to program. Formatting code properly just saves everyone lots of mental capacity understanding it. Good luck making sense of that code without watching it being written, I guarantee you waste a few minutes every segment.
@@cybroxde good point, but when i started coding i was a bit trash, so i got into reading this type of code
I still haven't figured out how to do this exactly your way, but I finally figured out how you did this. Basically, each line is directed at the cubes, and the main camera visualizes each of those lines as, well, lines. Except, the lines visualized by the camera are thick enough to hide the fact that you aren't using the limit of lines to process the rendering, making them blocky at the top and bottom. Regardless, these lines visualized by the camera change height by the distance of the ray pointed at one of the walls.
So, now I know that you could also do this on the z axis. By adding more rays on the z axis and changing the lines to be more like blocks, the new "blocks" can change height on a z axis and change width too(if you make the rays have semi-rays in-between)
If you didn't make this video, I wouldn't have figured this out, thanks!
your code is unreadable
Still better than mine
14:50 That sound effect has been used everywhere and thus driven into my brain.
I have been making video games in Unity as an amateur hobby game developer for several years, on and off. This looks so epic and cool that I feel inspired to dare dip my toes into pure code based game design and maybe create my own little 2D block-based level platformer engine. Just for fun!
Thank you so much. Raycaster for dungeons and mode seven for the overworld work so well on a tiny indi project to break out of the 2d and isometric mold.
i like fisheye effect, it makes it look even more realistic. Like see through camera lenses.
I was hoping to see a water link in the description
The advertisement was actually good and made me curious
yay, i did it! used SDL2 for graphics... had to work out some quirks in the initial version (mp >= 0 !!!) Thanks for this great tutorial! It got me motivated to give it a try finally
Wow thank you for the nice comment! :)
Cool sponsorship! I love water, I can't go more than a few days without it.
I just found you today and you like my favorite person already. I’ve also never heard someone else who does the S whistle with their teeth and tongue when saying some words. I’ve been messing with OpenGL and Vulcan the past few months and you are awesome
you are better than university professors. You teach in an easy to understand method.
My only suggestion would be is to have popup links to other videos at certain parts to explain certain things in more detail if people who are learning this want to have a better understanding of things such as the sin or cos or what a tangent is and ect.
I realize that, for brevity, you put so many ops on one line, but dear lord is it a nightmare to look at.
Great video!
The best ray casting tutorial on UA-cam!
Wow thank you! :)