Orion’s Gate: Real Time Ray Tracing concept
If you’re not aware – I am working on my own online game for quite a while now. However, one thing has been quite a pain in the ass to do – and that’s shadows. So I’ll be talking about that particular subject today.
Producing real-time shadows is one hell of a thing to accomplish. Luckily in this day and age, there are a few ways to go about this. These are:
Probably the most widely used technique of them all. The fast version is that you render from the light’s view, note depth values, render from real point of view, compare values, and determine which part is lit and what is in shadow. Sounds simple, it’s pretty difficult since you have to do something called Matrix Multiplication.
Volumetric Shadows aka Stencil Shadowing
This technique performs so-called Backface-Culling (find out which polygons can’t be seen by the camera), copies them, and extend them in a finite range, and make the overlaps visible with anything those “copies” hit. This usually produces pixel-perfect shadows – but it’s also very expensive to calculate.
After reading a lot about this shady (badum-tish) subject, I decided to go about it in a different way. I sat down and thought long and hard about a way that would sort of maybe meet both of them in the middle, or maybe use a new technique to do it.
I learned of a completely different technique, called Ray Tracing.
While super-easy to implement, even on easy scenes it can take quite a while to render the scene. There have been a few attempts at actual real time ray tracing, one of which can be seen here:
Now obviously that kind of setup and machine is a bit outrageous to aim for someone making a game. While this looks pretty good, pixel-perfect ray-tracing as seen in the video will remain in the domain of super-computing for now.
However, I came up with a way that utilizes a stripped down version of ray tracing, which is usable in today’s hardware. While it won’t produce super-mega-realistic shadows, or imagery, it does work as intended and produces accurate shadows with the help of light ray tracing.
I’ll outline the steps of the technique used, hopefully in a way that works for everyone.
1) Define a grid of a finite size, say 128 x 128 points. The higher this number, the higher the shadow detail – but also the more delay in ray tracing. You could think of this as the shadow map size.
2) Have a model in the size of exactly 1 x 1 unit compared to the grid, and place it at the start position (0 x 0 for example). Also, switch your view to the light’s position (IMPORTANT).
3) Start moving the model in one direction (horizontally or vertically, up to you), with the distance of 1 unit. Rendering is not required. You query whether or not the “scanner tile” can be seen from the light at its current location. When it hits the end of your plane, you move it back to 0 vertically and 1 unit horizontally, and again move it on that line to each place in the grid.
4) As you move the “scanner tile” on all possible locations on the grid, you mark down whether or not the tile was seen from a specific location. If for example a cube was blocking sight to the tile, that particular place has to be in shadow.
5) Now that you know what is in shadow and what is not, you can begin shading the scene. How you do it is ultimately up to you – I use simple two-dimensional GL_QUADS at those locations. I also take the distance of the tile to the light into account, and apply an alpha value to it relative to its position to the light, giving the effect of shadows fading out the further they are from the light.
It works like this:
Here are a few screenshots of the technique in action.
And to close this off, I’m showing the technique on video and explain it in simpler terms, if you’re interested.
Until the next worklog.