23 ms·
A first-person engine in 265 lines of JS
- eignerchris_ 12y agoThis is so great. Very straightforward explanation of raycasting. Looking forward to playing with!
- tst 12y agoAs someone with no experience in computer graphics it's always insane to see demos like this. Especially using just around 250 lines of javascript. Really impressive. Also on the topic, the demo scene stuff is mind blowing, too. [0] [0]: http://awards.scene.org/awards.php http://awards.scene.org/awards.php
- masterj 12y agoThe nice thing about this implementation is that the code is very clear and easy to follow. You could easily make it much shorter if that were the goal.
- huskyr 12y agoExactly. I think that's wonderful about this example, it's not just 250 lines of heavily compressed code, it's readable and clean.
- devindotcom 12y agoYep, kkrieger is the one I remember: https://www.scene.org/file.php?file=%2Fparties%2F2004%2Fbreakpoint04%2F96kgame%2Fkkrieger-beta.zip&fileinfo https://www.scene.org/file.php?file=%2Fparties%2F2004%2Fbrea...
- CmonDev 12y agoScripting languages are good for achieving low line count results.
- restlessmedia 12y agoMe three. It's covered the 're-read in 6 months time' criteria. I must confess I do change from reading to scanning as soon as the heavy math kicks in.
- DanBC 12y agoThere's a niche for a website that does a bunch of sub-500 LOC javascript examples of tiny bits of computer graphics, to give a very brief introduction and demonstration of the math, and which then chains them together for some other software.
- smrq 12y ago> Rain is simulated with a bunch of very short walls in random places. This made me laugh. I would have never thought of that way of doing it, but before I knew how it was implemented, I didn't even notice! That's a pretty good approximation!
- aaron-lebo 12y agoThat's really impressive. I've seen some people suggest that voxels are like sprites for 3d programming (as far as sheer simplicity goes), but this strikes even more so as that. How does this compare to using actual 3d/voxels? Can you still have interesting physics or do you miss out on a lot?
- hunterloftis 12y agoThanks! As with most software decisions, raycasters involve a tradeoff. They are related to voxels in that they impose constraints on what can be rendered. Voxels render grids in 3 dimensions while raycasters (typically) render them in 2. For this reason, you can generally build a raycaster faster and simpler than either voxels or meshes, but there will be things you can't do. Rotation on the x axis is tricky, for example. It's probably best to think of physics in a raycaster as the same sort of physics you could apply in a top-down 2D game.
- cwyers 12y agoI know that the arrow keys have actual arrows on them, but so many modern games have trained us to use WASD to navigate, that if you're going to insist upon the arrow keys for navigation, you should probably mention this somewhere before the link to the demo.
- hunterloftis 12y agodone!
- passfree 12y agoAwesome!
- chandrew 12y agoWow.
- mazak 12y agoI'm really surprised that it's 265 and not 256... I mean, there's got to be a good reason not to make it a round number, right? I'm mind blown anyways...
- hunterloftis 12y agoWas shooting for 256 but went over to implement touch events ;)
- Hortinstein 12y agothis is incredible. I remember doing something in C in openGL with triple the line count and not nearly as impressive results during a bachelor computer graphics class. This would have been a much more interesting lab. Thanks for the great work, i can't wait to play around with this!
- thinkersilver 12y agoRaycasting brings back memories! I remember poring through raycasting techniques to make my Wolf and Doom clones as a teenager. When I was almost done I demoed this for a group of friends at our school's computer club and boy were they were impressed up until the point the clipping algorithm failed and objects stopped disappearing when they fell out of the players field of view. Was teased for months after that. ... .
- callumprentice 12y agoGreat work. I had a huge amount of fun converting your last article (terrain renderer in a tiny number of JS) to WebGL and that was only fun because of your clean, easy to understand code. Thanks for sharing. --Callum
- devindotcom 12y agoHeh, reminds me of kkrieger - a first person shooter in 100KB for a scene demo. https://www.scene.org/file.php?file=%2Fparties%2F2004%2Fbreakpoint04%2F96kgame%2Fkkrieger-beta.zip&fileinfo https://www.scene.org/file.php?file=%2Fparties%2F2004%2Fbrea...
- timpark 12y agoIf you missed it a couple of weeks ago, this article about its creation was really interesting: http://fgiesen.wordpress.com/2012/04/08/metaprogramming-for-madmen/ http://fgiesen.wordpress.com/2012/04/08/metaprogramming-for-... ( Thread: https://news.ycombinator.com/item?id=7739599 https://news.ycombinator.com/item?id=7739599 )
- hnha 12y agothank you, the title did not interest me back then. Sometimes I wish HN was more like metafilter.
- devindotcom 12y agoThat's great! I did miss it.
- sclangdon 12y agoAnd here is Farbrausch's repo, which includes the .kkrieger code along with a lot of other interesting stuff. https://github.com/farbrausch/fr_public https://github.com/farbrausch/fr_public
- Myrmornis 12y agoIt's really interesting but would someone mind explaining why they have to keep this code under some size limit?
- DanBC 12y agoBecause they can. Because it's fun and challenging to do so. Because bragging rights.
- darkstalker 12y agoIt runs really slow for me, like 1 FPS. Firefox 29 on Linux.
- hunterloftis 12y agoInteresting. Does FF 29 on linux perhaps have purely software graphics? It runs much faster than 1 fps on iphones and most androids, 60 fps on modern desktops in safari/chrome, and 30 fps on FF / osx.
- jgillich 12y agoI get terrible FPS with Firefox on Windows as well (Intel Haswell graphics).
- joelthelion 12y agoWhat graphics card/driver combination do you have? It runs decently for me with Firefox 29 on Linux, intel graphics (Sandy Bridge).
- DanielRibeiro 12y agoIt is not using the GPU to do the drawing: https://github.com/hunterloftis/playfuljs/blob/master/content/demos/raycaster.html#L150 https://github.com/hunterloftis/playfuljs/blob/master/conten... Note that it is using canvas 2d rather than canvas 3d (aka WebGL[1]). But if you take ray casting to extreme, you end up with Ray Tracing[2], which is kinda expensive. Which is why we had such an effusive conversation a few months ago about hardware accelerated RayTracing[3]. A sample ray traced scene from AlteredQualia[4] (2nd largest[5] contributor to the famous Three.js Library): http://alteredqualia.com/three/examples/raytracer_sandbox_reflection.html http://alteredqualia.com/three/examples/raytracer_sandbox_re... [1] https://developer.mozilla.org/en-US/docs/Web/WebGL/Getting_started_with_WebGL https://developer.mozilla.org/en-US/docs/Web/WebGL/Getting_s... [2] http://en.wikipedia.org/wiki/Ray_tracing_%28graphics%29 http://en.wikipedia.org/wiki/Ray_tracing_%28graphics%29 [3] https://news.ycombinator.com/item?id=7425303 https://news.ycombinator.com/item?id=7425303 [4] https://github.com/alteredq https://github.com/alteredq [5] https://github.com/mrdocob/three.js/graphs/contributors https://github.com/mrdocob/three.js/graphs/contributors
- s-macke 12y agoMy raycast engine in Javascript needs a few more lines and works a little bit different, but gives also impressive results I think :) . http://simulationcorner.net/index.php?page=comanche http://simulationcorner.net/index.php?page=comanche
- hunterloftis 12y agoLove it! Thanks, just linked from the article.
- s-macke 12y agoHey thanks, that was fast.
- nppc 12y agoI really like how your code uses much less cpu than that of the article. whats the trick ?
- s-macke 12y agoDon't know. But here some possibilities: 1. No fullscreen 2. I update the screen only if a key is pressed.(No rain, that has to be rendered all the time) 3. I don't use any costly canvas functions. I render everything myself in a pixelbuffer. 4. Typed arrays
- hunterloftis 12y agoIt's #2. Redrawing at 60hz (or as close as the machine can come) is what hits the cpu so hard.
- s-macke 12y agoNo, I don't use requestAnimationFrame right now. I think when I wrote it, it was not supported by IE. But can't remember. I calculate as close as the machine can but with a window.setTimeout(Update, 0); in order to be responsive.
- roryokane 12y agoIt is very interesting to me that you need to multiply the distance-to-wall by the cosine of the angle to transform the image from fisheye to normal. It makes me wonder, why is it that our eye in real life sees straight lines as straight, the way this demo renders the image? To illustrate the question, see https://en.wikipedia.org/wiki/File:Panotools5618.jpg https://en.wikipedia.org/wiki/File:Panotools5618.jpg – why do we see the world as in the bottom image instead of in the top one? After all, our eye really is at different distances from different parts of a straight wall, so it sounds logical that we would see the fisheye effect describe in the article. Is the rectilinearity of the image we see caused by the shape of the lens in our eye, or by post-processing in our brain?
- deleted 12y ago[deleted]
- NAFV_P 12y ago> It makes me wonder, why is it that our eye in real life sees straight lines as straight, the way this demo renders the image? Not always. Next time the Sun and the Moon happen to be in view at the same time, look at the dividing line X on the Moon between the parts illuminated and in shadow. Then draw a straight line Y from the Moon to the Sun. Common sense tells us that the two lines are perpendicular, but often this is not the case. I don't understand it completely myself, but it is something to do with us residing on a curved surface.
- toki5 12y agoI would hazard a guess that it's a result of the brain interpreting the electrical impulses before providing the "image" that we "see." It does a lot of pre-processing, so to speak -- which is why we get such awesome illusions as the Poggendorff illusion [0], tricks like the Pulfrich effect [1], etc. I don't know enough about the mechanics of how light enters and is interpreted by the eye, but I wouldn't be surprised at ALL if we "should" be seeing more like a fisheye lens but our brain is saying no, no, those lines are straight, based on the countless other stimuli it's receiving. [0] http://dragon.uml.edu/psych/poggendo.html http://dragon.uml.edu/psych/poggendo.html [1] http://en.wikipedia.org/wiki/Pulfrich_effect http://en.wikipedia.org/wiki/Pulfrich_effect
- riquito 12y agoCool. It reminded me of a similar work published by Opera some years ago http://dev.opera.com/articles/3d-games-with-canvas-and-raycasting-part-1/ http://dev.opera.com/articles/3d-games-with-canvas-and-rayca... woa! it was 2008, time sure pass by.
- pearjuice 12y agoI feel very pathetic from this. You could have given me 265K lines and I wouldn't have figured it out.
- jiggy2011 12y agoPretty sure the author followed this tutorial. http://lodev.org/cgtutor/raycasting.html http://lodev.org/cgtutor/raycasting.html
- hunterloftis 12y agoDon't feel pathetic! I certainly didn't invent anything here, I just distilled an old technique as much as I could in JS. Besides, we all start somewhere mate.
- Cieplak 12y agoReminds me of http://www.p01.org/releases/20_lines_Castle_Wolfenstein/ http://www.p01.org/releases/20_lines_Castle_Wolfenstein/
- JulienSchmidt 12y ago<rant about no. of lines being a completely useless metric> <jquery in 1 line>
- olegbl 12y agoI remember being amazed how simple raycasting was when I wrote a similar (though much simpler) engine in Java for a high school project. The "engine" itself was like ~200 lines of code in just 2 or 3 functions. Raycasting is a really clever technology. Cool demo!
- pervycreeper 12y agoThis demo unfortunately uses an incorrect perspective transformation. There is no reason to go to trig if you represent the camera plane as a vector, and step along it one pixel at a time, and allowing the wall height to vary linearly in the distance to the camera vector (taking lines to lines). In addition to being correct[1], it has the added benefit of being faster if implemented well. My (admittedly n00bish and embarrassing) attempt at doing the same thing is here: https://github.com/pervycreeper/game1/blob/master/main.cpp https://github.com/pervycreeper/game1/blob/master/main.cpp [1] in the sense that lines map to lines, as in most photography, Renaissance and later painting, and most computer graphics
- sillysaurus3 12y agoWhy is it incorrect? From looking at the demo, it doesn't seem incorrect at all. If it's incorrect, then the incorrectness doesn't affect the end product, which is all that matters. Lines seem to map to lines, so it seems mistaken to call it incorrect. I'd be interested in further explanation about why you feel the underlying math could be improved, though.
- pervycreeper 12y agoHe ought to be using what Wikipedia calls a "perspective projection", or, sufficiently in this case, a restriction thereof. Notice how the edges of walls do not appear straight on the screen, even though he mentioned correcting "a fisheye effect" (tellingly alluding to a popular tutorial on this topic at lodev.org). A correct formula is on line 485 of my implementation linked above, found the old fashioned way using basic geometry.
- sillysaurus3 12y agoIndeed, you're right: http://i.imgur.com/oQ7S3Jo.jpg http://i.imgur.com/oQ7S3Jo.jpg On my old laptop, the demo looked fine. But after switching over to a widescreen (and higher FPS) you can tell that it's slightly wrong up close, and noticeably wrong (jittery) in the distance. I wonder what's causing the jitter...
- matheusbn 12y agoNice demo! But one note, I don't know about DaggerFall but Duke Nukem 3D does NOT uses Raycasting to draw walls. DN3D uses sectors (Convex Polygon) to store room's lines (or walls), and draws those lines using player's FOV (Field Of View). When those sectors are connected with others sectors, it's called portal. This is used to sort only the sectors that is inside the player's FOV.
- hunterloftis 12y agoThanks for letting me know! It's referenced as a raycaster in several places, and of course the output looks very much like a raycaster's, so I checked up on this. After a little reading, it sounds like DN3D uses a cousin of a raycaster, as it's still rendering independent columns. Instead of casting rays to find them, it's projecting their vertices. Neat!
- thedevopsguy 12y agoDidn't games like Duke Nukem 3d, post-Doom, Wolf games use what was called a scanline algorithm? Drawing the lines in the players FOV as you just stated and then using a clipping algorithm to keep unwanted information out. I think raycasting would be a type of scanline algorithm, but the technique is less primitive since your not using a proper 3d engine. It's a long time since I programmed games like this so am now a bit fuzzy on the specifics.
- elnate 12y agoWhat's the difference between ray casting and ray tracing?
- Drakim 12y agoWikipedia gives a pretty good breakdown of the two terms: http://en.wikipedia.org/wiki/Ray_tracing_(graphics) http://en.wikipedia.org/wiki/Ray_tracing_(graphics) http://en.wikipedia.org/wiki/Ray_casting http://en.wikipedia.org/wiki/Ray_casting
- rukke 12y agoA raycaster in 254b on the C64 https://plus.google.com/108984290462000253857/posts/MxWQwo14GNS https://plus.google.com/108984290462000253857/posts/MxWQwo14...
- Kiro 12y agoWhy do you need to use Uint8Array and not just a normal array?
- hunterloftis 12y agoI (mistakenly) thought it would access faster. In looking for benchmarks to link you to, I found out that's a false assumption. So - no reason to at all :)
- mobiuscog 12y agoAnd it even manages to include Google Analytics !