The concept of true 3d in Doom Legacy.
By Steven McGranahan
Table of Contents:
Chapter 1: The Beginning
Chapter 2: The Lowdown
Chapter 3: Your first level with 3D floors
Chapter 4: Linedef code summery
Chapter 5: What causes slowdown?
Chapter 1: The Beginning
Close to a year ago, the DosDoom team shocked the Doom community with an
animated gif of a doom level with a real, true 3d bridge that the player
could go under and over. Now, DosDoom has become EDGE and true 3D has become
one of it's main features. The method EDGE uses for it's true 3D is a very
simple and powerful one. It is capable of doing much more than just sector
over sector, with EDGE's 3D, the level designer can create complex 3D structures
and architecture.
About 8 months ago, I began a series of experiments that were designed
to simulate true 3D in my favorite Doom source port, Doom Legacy. These
coding experiments eventually lead me to create invisible solid regions
in a sector that objects could stand on top of and below. Then the DosDoom
team released their source code and I downloaded it to try to copy the
rendering code for 3D floors to complete the invisible ones I had made.
Probably 4 attempts at this failed just miserably, and I gave up on rendering
3D floors (I had also made several attempts to turn Legacy's translucent
water into 3D floors, but without success).
Legacy would not be able to render 3D floors until DosDoom became EDGE
and the source was released. When the EDGE team released the code, I saw
some of the pictures of things they had done with 3D floors and I knew
that I had to try again. So I began to copy the code once again, and this
time, was successful. Now, EDGE used GLBSP for rendering levels (even in
software) which meant that the code it used to render them with the normal
Doom BSP was outdated and very limited (only one 3D floor per sector, they
did not effect lighting, and sprites were not sorted with 3D floors correctly)
and thus it was up to me to bring this code up to date. This is what I
have been doing that last 6 months.
So far I have managed to increased the 3D floor plane limit and the 3D
side limit to 20, I have made it possible for 3D floors to cast shadows
on the surrounding walls, and floors, and I have made a much better sprite
sorting system (although it is still flawed). In fact, about 80% of the
3D floor code is now my code from scratch.
Chapter 2: The lowdown
So you want to know how things work, eh? Well, first I would like to state
that 3D floors in Legacy are not perfect. They are plagued by bugs in the
original Doom rendering system, and many visual bugs you may notice are
not fixable unless I overhaul the rendering system (which is probably not
going to happen). These bugs, however, are now very few and far between,
and if you are careful, you can avoid most bugs.
There are known speed issues. A 3D floor (as of 01/10/2001) will slowdown
Legacy about as much as adding 3 sectors. That is to say, every 3D floor
that is tagged to a sector so tagging a 3D floor to, say, 3 sectors, will
slow down the game about as much as if you added 9 sectors to the map.
I will explain in greater detail later on, what exactly causes the game
slowdown and how to minimize it.
Chapter 3: Your first level with 3D floors
Ok, you want to put a 3D floor into your level? Ok. First, I want you to
understand that I am not here to teach anyone how to use their editor of
choice. You need to understand how to tag a line to a sector and how to
set a linedef type.
First, build a small, 5 sector level to match the image below (NOTE: These
shots were taken using a now defunct level editor called DIE (R.I.P.) which
is not available any more, which is ok because it never really got anywhere
but WA is crashing for some really weird reason so I'm using DIE to take
screen shots) heh.

Note: I added the line lengths myself.
Sectors A and B should have a floor height of 0, a ceiling height of 128,
and a light level of 255. Sectors C, D, and E, should have a ceiling height
of 128, a floor height of -64, a light level of 255 and make the floor
texture something painful (like lava or nukage). Now, texture everything
in and add a player to the left-hand sector and run the map. If you chose
the same textures as me then it should look something like this:

OK, so now we need a bridge across the lava. Now we could just raise the
floor of sector C to accommodate our marine. However, this method of creating
a bridge really sucks because it doesn't allow for passage UNDER the bridge,
so we are going to create a 3D bridge to get us across.

First, we need to make a control sector. This is a small, off map sector
that will contain the textures and attributes we'll need to make a 3D structure.
The size and shape of this sector does not matter. NOTE: I usually make
my control sectors a triangle and "point" them at whatever they effect.
It makes them easier to keep track of.
Now set sector F's floor height to -8 and it's ceiling height to 0, and
set both floor and ceiling textures to FLOOR4_8, and set F's light level
to 176. Then, select one of the linedefs, set the line special to 281 (281
is the linedef code for a solid, opaque, 3D floor) and tag it to sector
C.
Now sector F will be a "model" for a 3D floor in sector C. Sector F's floor
will be the model for the "bottom" of the 3D floor, and it's height and
texture will be used accordingly. The same applies for the ceiling of sector
F, it's ceiling texture and height will be used. The texture for the sides
of the 3D floor will be the middle texture of the linedef with the 281
special, and finally, the light level of sector F will be the light of
the shadow it casts.
what's left? Nothing! Run j00r map!
Chapter 4: Linedef code summery
281 - Creates a solid 3D floor in all tagged sectors.
289 - Creates a solid 3D floor in all tagged sectors, does not cast a shadow.
300 - Creates a solid translucent 3D floor in all tagged sectors.
301 - Creates translucent 3D water in all tagged sectors.
302 - Creates 3D fog (uses control sector's colormap) in all tagged sectors.
303 - Creates a 3D light (at control sector's ceiling height) in all tagged sectors.
304 - Creates a 3D light (same as 303 except the 3D light is reset at control sector's floor height)
Expect detailed explanations of each linedef type soon...
Linedefs 300 and 301 support an alpha value in hardware mode:
uppertexture: [#000..#255] (#000 = transparent, #255 = opaque. If not defined, the default value is #127)
   
Chapter 5: What causes slowdowns
    Slowdowns are caused mainly by overdraw. Overdraw means that a
pixel on the screen is drawn more than once. In the Doom renderer, overdraw
is avoided almost completely by using 2D clipping. However, this method would
not be suitable for 3D floors so a new method had to be incorporated: sorting.
    Sorting takes all the sprites and 3D floors and arranges them so
that they will draw in the correct order. This method is not very time consuming
and works well for ordering the scene. Most of the time, this method works
flawlessly. A few bugs remain here and there, but it's pretty solid.
    Slowdowns related to 3D floors is generally caused by all the extra
scene components that Doom has to draw (i.e. 3D sides and all the extra
floor/ceiling planes), and because of this, slowdown is generally related
to two factors in your map: number of stacked 3D floors in a sector, and the number
of subsectors in a sector.
    Controlling the number of subsectors a sector has is pretty much
impossible, because different node builders will chose different partition lines
to start building nodes with, which will lead to different subsector configurations.
However, you can control the number of linedefs in a 3D floor. If you create
a grate with a 3D floor, you will, in effect, create new subsectors. Keeping 3D objects
simple will help reduce rendering times.