andrewj
Senior Member

Posts: 1380
Registered: 04-02 |
I've been hoarding a good idea on how to closely emulate the Doom light fading in an OpenGL port. Seeing that I'm done with Doom, I may as well share it:
First thing: it requires splitting polygons. But you don't need split every polygon in the scene, and the split process maintains polygon edge compatibility (i.e. it doesn't introduce "gaps" caused by neighbouring edges having different start/end coordinates).
The split line (on the 2D map) is always perpendicular to the view angle, and away from the view point by a distance D. They extend to infinity. Any polygon which crosses a split line must be split, which is not trivial but not too hard either.
There are five split lines: D=0, D=+200, D=+1000, D=-200, D=-1000. You can skip the two behind the viewplane when the mlook angle is small enough (<= 45 degrees or so from the horizontal).
Let LITE(sec,dist) be the Doom lighting function, where the sector lighting and result are in the range 0-1. It's something like this:
LITE(sec,dist) = sec * 2 - 1 + 40 / dist
Compute the lighting value at the split distances:
L0 = LITE(sec,0)
L1 = LITE(sec,200)
L2 = LITE(sec,1000)
After polygons are split, they lie entirely in one of three ranges (0-200, 200-1000, 1000-infinity). For polygons in the 1000+ range, just give all their vertices a single color: L2 * white.
Polygons in the range 0-200: compute the vertex color by LINEARLY interpolating between L0 and L1 based on 2D distance of vertex to the viewplane. Similar for range 200-1000.
Because OpenGL also linearly interpolates the colors of a rendered triangle, the above method should ensure a consistent result (no mismatches between neighbouring polygons).
This method has the big advantage of not using the OpenGL FOG mechanism, which as you know always fade to solid black at some distance, making it really unsatisfactory for emulating the Doom fading. My method should work even on old cards like the Voodoo3. You can also increase the number of split lines to improve the emulation (at the expense of more splits == lower performance).
Last edited by andrewj on 12-19-05 at 06:32
|