Wall wiggle bug

From DoomWiki.org

A demonstration of the wall wiggle bug in a high-resolution source port.

In the Doom engine, the wall wiggle bug, also known as the floor wiggle or wobbly line bug[1], is a graphical glitch most often apparent when a player is positioned in such a way that a two-sided linedef passes almost directly through the center of the player. Due to the nature of the glitch, it is generally observed when the player is standing at the boundary between two sectors with different heights, such that there is a ledge visible above or beneath the player. The glitch results in the line demarcating the ledge appearing to "wiggle" back and forth in a distracting and unrealistic manner as the player moves.

While the glitch has been present since the original release of Doom, it was not widely noticed until the advent of high-resolution source ports, due to the unusual aspect that the glitch actually becomes more severe as the engine's resolution increases. It may have been alluded to by John Carmack in the notes for the original Doom source code release, where he mentions regretting the use of "polar coordinates" for purposes of clipping,[2] as this code along with other functions relies on global trigonometric look-up tables with limited precision which are indexed by the player's view angle.

Technical[edit]

The bug arises from the following code in the R_ScaleFromGlobalAngle function:

anglea = ANG90 + (visangle-viewangle);
angleb = ANG90 + (visangle-rw_normalangle);

// both sines are allways positive
sinea = finesine[anglea>>ANGLETOFINESHIFT];
sineb = finesine[angleb>>ANGLETOFINESHIFT];
num = FixedMul(projection,sineb)<<detailshift;
den = FixedMul(rw_distance,sinea);

if (den > num>>16)
{
	scale = FixedDiv (num, den);

	if (scale > 64*FRACUNIT)
		scale = 64*FRACUNIT;
	else if (scale < 256)
		scale = 256;
}
else
	scale = 64*FRACUNIT;

return scale;

To summarize, the Doom engine calculates how far the line is from the player's point of view at each visible end of the line, and uses this to determine the scaling factor that should be applied to the line at each end. In the case where the line passes extremely closely to the center of the player, this means that the scaling factor for the line would be extremely large at one end, because the player's viewpoint is infinitesimally close to the line.

A demonstration of the severity of the wall wiggle bug at different resolutions.

The engine, however, enforces a maximum value for the line's scaling as 64*FRACUNIT. This limit is implemented because the engine must use fixed-point arithmetic to determine the final amount to scale a linedef texture, and an extremely large scaling factor would overflow the limit of the variable type used.

In practice, this means that a line that passes almost directly under or over the player will appear to bend away from the player. This is exacerbated by the fact that the Doom engine using precalculated tables for the sine and cosine values used to calculate the scaling factor, and near the edge cases where the engine is attempting to divide by a precalculated value extremely close to zero, the coarse nature of the tables can result in a very large multiplicative value that can instantaneously shift by a large amount.

Most source ports which have implemented high resolutions have not implemented any measures to address this bug, and continue to use the same fixed-point arithmetic to determine linedef scaling factors; because the ports generally increase the detailshift and projection values in the process of implementing higher resolutions, the result is that the scaling factor reaches its limit at even less oblique angles, and the wall wiggle becomes more common and more noticeable.

Workarounds have been developed to limit the severity of wall wiggle within the original engine framework[3], but because the bug is related to the fundamental workings of the Doom engine's renderer, it cannot be eliminated without a significant rewrite of the rendering code.

The Eternity Engine eliminated this error in 2006 through Stephen McGranahan's floating-point Cardboard renderer. ZDoom is also known to have fixed this error in its software renderer. All hardware-accelerated source ports eliminate the bug by default.

References[edit]

  1. James Haley (Quasar) et al. (12 October 2006). "Solution to wobbly line problem that *doesn't* involve Build code?." Doomworld Forums. Retrieved 6 January 2015.
  2. John Carmack (23 December 1997). "README.TXT." Doom source code. Retrieved 6 January 2015.
  3. kb1 et al. (25 September 2014). "Dynamic wiggle/Tall Sector fix for fixed-point software renderer." Doomworld Forums. Retrieved 6 January 2015.