OK, let's first review how shading and visibilty work in classic. When an object is drawn, for each pixel [*] of that object, a shade index is determined according to a single formula:
shidx = clamp(shade + C*visdist, 0, Numshades-1)
Here,
shade is the object's shade while
visdist is the product of some visibilty and the distance from the eye to that particular pixel. In other words,
shade is constant throughout the object, but
visdist in general changes for each pixel (in shader terminology, one is uniform and the other is varying).
Clearly, the shade index is always greater or equal than the object's shade, and increases linearly with both distance or visibility (keeping the respectively other constant) until the maximum index, Numshades-1, is reached.
Given that formula, we can turn it "inside out" and instead ask for the starting and ending distances of a linear fog. At the starting distance, there's no attenuation, whereas at the ending one, it's fully black. E.g for the ending distance, plugging Numshades-1 into
shidx and solving for
visdist gives:
Numshades-1 = shade + C*visdist
-->
visdist = (Numshades-1-shade) / C
or
distend = (Numshades-1-shade) / (C*vis)
So far, so good. Let's see the starting distance. Plugging 0 in
shidx and doing the same procedure, we get
0 = shade + C*visdist
-->
visdist = -shade / C
or
diststart = -shade / (C*vis)
This is exactly the pair that I
introduced with
r_usenewshading 2. But there's a problem with it: in determining the starting distance this way, we assume that
no brightness attenuation has previously been applied to the object! To see why, consider the attenuation at distance zero,
(0 - diststart) / (distend - diststart) = shade / (Numshades-1).
Since in Polymost, objects are drawn with shading already applied (either using glColor(), or with
r_usetileshading, by using a texture obtained by doing the palookup on it), we're doing the intended shading twice. This is the only thing that was changed: with
r_usenewshading 3, the starting distance is always zero, reflecting the fact that the object has already been shade-attenuated. The ending distance remains the same, so the overall change is a homogenous increase in brightness for any set of objects with equal visibility.
Now, how does the new mode fare in practice? It is more faithful to classic as far as ratios of shade are concerned. For example, looking at the cinema entrance in E1L1,

the sector below the announcement tableau has infinite visibilty (240) and shade 11. The surrounding sidewalk has shade 4 and finite visibilty 0. [**]
Since the inner sector's floor always has the same brightness independent of distance, moving closer to it will make the sidewalk brighter in comparison, while moving away from it will make it darker. At a certain distance, both appear of the same brightness. This distance where both effects offset each other is correct with
r_usenewshading 3, but wrong with the old mode.
After having made the screenshots (gamma-corrected to 1.5 with ImageMagick), I do notice that the sidewalk appears brighter than in classic with the new mode now. However, for me, the difference doesn't look so striking in-game for some reason.
----------
This was part one of Helix' explanation of EDuke32 shading. Stay tuned for part two, wherein the mysteries of
r_usetileshades are unveiled and an attempt is made to convince everyone that
r_usetileshades 2 is in a certain respect more faithful in reproducing classic (but less so in another one).
Edit: corrected horizontal <-> vertical in the first spoiler.