RayCast.js Engine Demo
HTML-код
- Опубликовано: 21 авг 2024
- Make sure to check out the latest demo at • RayCast.js Engine Demo...
______________
A quick demo of my Wolf3D-esque grid-based raycaster engine. I have been working on pushing various new features, which include but are not limited to:
* Fully textured floor, ceiling and walls
* Player elevation
* Support for looking up and down (perspective-incorrect, achieved via y-shearing)
* Walls of varying heights
* Diminishing lighting (fog effect)
______________
The engine was written from scratch in pure, vanilla JavaScript-no external dependencies and runs on all major browsers. I tested mainly on Firefox, Chrome and Safari.
Check out the live demo at: undefbehav.itc...
GitHub: github.com/emr...
The music used in the video is composed by Jim Hall and is titled 'Last Breath'.
Outstanding work!!! Congrats!!
Haha, thanks man! Coming from a fellow 3D programmer, I really appreciate it! :D
@@undefBehav You're welcome. I tried it out yesterday and notice that it runs considerably faster on Chrome that in Firefox, if that's useful. It may be my PC, though.
Also, I notice something weird just walking around. Are you y-shearing the camera while walking?
@@adrikriptok7225 Thanks for sharing some insights. That's weird though, I thought Firefox and Safari had faster JIT compilers in comparison to that of Chrome. Nevertheless, my main goal is to shoot for approximately 30 fps, I still have room for optimizations in the occlusion culling code in that regard.
As for the y-shearing effect, I am ever-so-slightly decreasing the height of the camera while walking to give the first-person perspective the impression of walking. However the *actual* y-shearing is when looking up/down (with arrow up & down keys).
I have recently added mouse support, which improved the free-look experience immensely IMO. However they are not live yet. I am going to deploy those changes with the new map that I had created for the purpose of this video.
Thanks again for your interest in my little engine. :)
@@undefBehav My mistake, then. But I also noticed something weird with the shading on diagonal walls. It's like when looking at a diagonal wall from some angles, the shading doesn't cover the whole wall. I wish I could post images here to show you what I mean :S
@@adrikriptok7225 No, I did exactly get what you mean by that. Diagonal walls are not actually complete, they still need fixing as their texture-mapping is not complete. :D I was prototyping with implementing some hard-coded diagonal walls long ago but never got around to completing their texture-mapping. That’s because I was always prioritizing to get the walls with varying heights working.
wow very impressive demo ! can i ask you some questions when i start implementing my version :) ? also do you already have an idea how to code enemies ai ? great work man, keep it up !
Thank you! I really appreciate it. This literally is nothing though, compared to your fully-3d engine with all its occlusion culling and perspective-correct texture mapping. XD Anyways, please do shoot any question you may have, I would love to chat and discuss about 3d graphics tech, I have *A LOT* to learn from you! You too keep up the great work!
This is Made in Javascript?!
Amazing !!!
That’s right, thanks!
On one hand, I don't get the appeal of real-time ray-tracing when it's so demanding for such little improvement. On the other hand, I realize other people like it, and you're doing a damn fine job making a source port built around it. Keep it up.
Hey thanks! But this is not a source port, it's a stand-alone ray-caster engine written from scratch.
also ray casting vs ray tracing different things
Might try using this to make a retro style multiplayer shooter
Sure, go for it! Let me know when you're done so I can give it a shot. Good luck & have fun!
this is so cool
Kewwwwl
Nicely done. I didn't realize it was possible to efficiently texture map walls and ceilings in JavaScript. The Permadi JavaScript examples seem to be much slower than yours. I might go back to using JavaScript to prototype.
Haha, thanks. Well, it actually took me *many* iterations of different approaches to texture-mapping before I could settle for ~30 fps, but I feel pretty good with what I got so far. However I believe there is still much room for optimizations/improvements.
There is actually nothing elegant about rendering texture-mapped floor and ceiling surfaces-Permadi's tutorial, as well as popular engines in the 90s, like Doom engine and Build engine, all follow the same approach: interpolate the distance between the player and edges of a wall strip and use that to query the texel on a per-pixel basis. The main optimization I did there was to quit relying on canvas API's `drawImage` which was slowing things considerably. Instead I incorporated in an 'offscreen' canvas and did all the rendering on it manually to buffer the screen bitmap data before flushing it to the actual canvas. This was a huge improvement over calling drawImage for each pixel. Other than that, I ditched my painters' algorithm-based approach in favor of occlusion tables to avoid overdrawing for the varying wall heights. I draw solid geometries in a near-to-far fashion while updating which pixels are occupied on the screen and clip the walls that are further accordingly.
@@undefBehav Wow, the rendering algorithm you've described seems to be the same approach I'm using for my grid-based FPS engine.
@@adrikriptok7225 Haha, I believe our minds work alike :D
Didn't firefox port the entire doom engine back in like 2012?
Its amazing
Impressive! :o
At 0:05 i see some sort of object rendering. How did you managed that? Also, how did you managed wall with different width?
The only non-solid objects in this engine are translucent walls (not present in this particular demo) and 2d sprites-which can be seen at 0:18 and 0:37. Other than those, all of what you see in this demo are a bunch of solid geometries.
As for the walls with arbitrary widths/depths, it is actually not much different from implementing them in varying heights. At each location on the map (which is actually a 2d grid of cells) I store bunch of data regarding the corresponding cell, among which are its height, depth and width. This way I can work out exactly on which point a given ray within the camera’s field of view will intersect an arbitrary-width/depth block. The same goes for arbitrary-height blocks, only difference is this time an intersection is calculated along the projection plane.
beautiful, is there a tutorial?
Please do a tutorial on this! I want to learn..
I‘m actually considering doing some sort of tutorial sometime in the future.
I need to learn how to make that y-shearing thing... All my raycasting attepts look like shitty wolfeinstein
Well, all I did was to literally change the height (game-world y-coordinate) of the viewport to give the illusion of camera pitching.
nice. can it run as glsl only tho??
I can use it into my JavaScript game?
Sure! You just need to have the patience to navigate my horribly written code which gets only worse with time.
gpu accelerated, try entity sphere collision volume distance field ray tracing, 3d or actual 3d ray tracing, cpu and gpu
I didn’t think it was possible for a raycaster to have varying heights. This isn’t bsp?
Nope, this is 100% ray-casting. Spatial partitioning/surface visibility determination has nothing to do with the geometries you can render actually.
@@undefBehav ok!
Strange
What is?
So, it's textures you need?
Yup.
@@undefBehav I can texture
@@Matzu-Music Awesome! Would it be okay if I use them in my engine? I use this engine just for my very own educational & entertainment purposes, nothing commercial.
@@undefBehav Sure, just what textures do you need?
@@Matzu-Music Well, anything goes-as long as it carries similar aesthetics and feel as classic Doom textures. Could be floors, ceiling, stairs, sky, you name it.
puha olmuş
sağ ol panpa
Can anything be done to improve the field of view?
Like improve in which way?
@@undefBehav widen it just a bit. Looks like a bit of tunnel vision. Make it closer to 80-90 degrees? I'm not too familiar with the math so I don't know if it's a simple matter of tweaking a value or a complicated effort
Is this a real raycaster, or this uses some technic like bsp? I was able to create a raycasting demo with floors but if I tried to add multiple heights the demo would become unplayable
Yes, this is strictly a raycaster. To prevent overdrawing, however, I had to come up with my own custom depth-sorting algorithm and occlusion culling routine for the walls/blocks with varying heights.
@@undefBehav thanks for answering
@@GabrielMartins-wp6ps No problem!
BSP is not a rendering technique. "I render my walls using BSP" doesn't mean anything. The proper way is to say "I render my walls with translations, but i optimize the drawing order via the use of BSP trees". Instead of using "painter's algorithm". With painters algorithm, you just draw everything back to front. The use of bsp's removes the overdraw, which in most cases speed things up.
It's a tad annoying when people somehow think that BSP is how something is rendered on the screen, when it's about in what ORDER things are rendered on the screen.
Anyway, nice project you got there Emre! Good work!
@@InnerTranquility That's a really nice point! I see people everywhere mistake the these concepts for one another as well. Very much like how Doom uses BSP, Duke Nukem 3D's Build Engine uses the portal technique for visible surface determination/occlusion culling.