Hardware Accelerated Raycaster
Posted: Thu Nov 03, 2022 9:53 pm
Just thought I'd add my entry to the already overflowing pile of raycasters.
The title might be a little misleading, but I have to get clicks somehow While I think my approach is reasonably novel, I'm sure it's been done before. That said, I didn't find any examples (not that I looked super hard).
I'd been playing a lot of 90's style shooters (Ion Storm, Project Warlock, Lead Haul, Gungodz) and fancied making something similar of my own. I wrote a software raycaster that could render a 320x200 frame in about 8ms on my 2013 MacBook Pro. While this was probably reasonable performance for the kind of thing I was going to do it felt a bit disappointing and I got bored and left the idea for a few weeks.
After some random messing around with Love and realising the shaders are proper GLSL shaders I thought I'd revisit the racyaster with an idea had a few years ago for a hardware rendered version. Essentially all the data required for plotting pixels is gathered into a texture which is submitted to a shader for drawing. With a bit of fiddling around I was also able to use proper depth buffer for occluding the sprites. Floors and ceiling are rendered with a Mode 7ish style shader, there's plenty of those knocking around on here.
As plotting the pixels is normally the slowest part of a raycaster, and GPUs are obscenely good at that part the performance boost is quite crazy.
For a 320x200 frame the machines I tested on get the following:
PC (i9-9900K, 32GB, 1070ti): <1ms, ~300-600 microseconds (~1-6ms for a similar scene in the software version)
2013 MPB (i5-4882U, 8GB, Integrated GPU): 1-3ms
The really cool part is that it can render a frame at 3840x2400 on the PC in about 1-3ms, and the native resolution of the MBP, 2560x1600, in about 2-4ms. The old Mac can't really run at the higher resolution.
Nearly all of the frame time is now taken up by the raycasting, and it's still possible to tank the performance by trying to render really large open rooms with very long draw distances. The draw distance can be configured. For lower screen resolutions lower draw and shading distances actually look better as there's too much "pixel crushing" (not sure of the real term, but I'm referring to the noisy textures on far walls) on distant textures.
I've attached a demo with some simple UI (thanks to Slab) for changing the renderer's parameters. You can enter or exit "walk around mode" by pressing tab. I'm curious to hear how it performs for other people, particularly on quite slow machines.
github: https://github.com/marclurr/harc
And a video for anyone who can't be bothered downloading, but wants to see:
Edit: Added link to github
The title might be a little misleading, but I have to get clicks somehow While I think my approach is reasonably novel, I'm sure it's been done before. That said, I didn't find any examples (not that I looked super hard).
I'd been playing a lot of 90's style shooters (Ion Storm, Project Warlock, Lead Haul, Gungodz) and fancied making something similar of my own. I wrote a software raycaster that could render a 320x200 frame in about 8ms on my 2013 MacBook Pro. While this was probably reasonable performance for the kind of thing I was going to do it felt a bit disappointing and I got bored and left the idea for a few weeks.
After some random messing around with Love and realising the shaders are proper GLSL shaders I thought I'd revisit the racyaster with an idea had a few years ago for a hardware rendered version. Essentially all the data required for plotting pixels is gathered into a texture which is submitted to a shader for drawing. With a bit of fiddling around I was also able to use proper depth buffer for occluding the sprites. Floors and ceiling are rendered with a Mode 7ish style shader, there's plenty of those knocking around on here.
As plotting the pixels is normally the slowest part of a raycaster, and GPUs are obscenely good at that part the performance boost is quite crazy.
For a 320x200 frame the machines I tested on get the following:
PC (i9-9900K, 32GB, 1070ti): <1ms, ~300-600 microseconds (~1-6ms for a similar scene in the software version)
2013 MPB (i5-4882U, 8GB, Integrated GPU): 1-3ms
The really cool part is that it can render a frame at 3840x2400 on the PC in about 1-3ms, and the native resolution of the MBP, 2560x1600, in about 2-4ms. The old Mac can't really run at the higher resolution.
Nearly all of the frame time is now taken up by the raycasting, and it's still possible to tank the performance by trying to render really large open rooms with very long draw distances. The draw distance can be configured. For lower screen resolutions lower draw and shading distances actually look better as there's too much "pixel crushing" (not sure of the real term, but I'm referring to the noisy textures on far walls) on distant textures.
I've attached a demo with some simple UI (thanks to Slab) for changing the renderer's parameters. You can enter or exit "walk around mode" by pressing tab. I'm curious to hear how it performs for other people, particularly on quite slow machines.
github: https://github.com/marclurr/harc
And a video for anyone who can't be bothered downloading, but wants to see:
Edit: Added link to github