Partial invisibility effect

From DoomWiki.org

A spectre, a partially invisible monster

The partial invisibility effect (also known as the fuzz effect and flagged as MF_SHADOW in the thing definitions) is a visual effect which is used in Doom for spectres and for the partial invisibility player powerup. The engine is technically capable of applying the effect to an arbitrary thing, but by default it is only used for the aforementioned. Heretic, Hexen, Strife, the majority of console Doom ports, and some source ports do not use this effect at all, either omitting it or relying on true or table-based translucency instead.

When a partially invisible thing is drawn in Doom, instead of drawing the usual pixel data of the thing's sprite, the engine copies pixels from the background. The space occupied by the sprite is filled with the fuzz effect by copying vertically adjacent pixels in a fixed pattern (the fuzz table, defined in an array in r_draw.c) inside the framebuffer while darkening them by applying the sixth colormap (counting from zero) to them. The final result is that the sprite appears as a translucent shadow, stippled and somewhat darker than the area of screen it was drawn over.

Vertical cutoff[edit]

Partially invisible player sprite being cut off at the bottom in Doom II version 1.9. Also, note that a wave pattern can be seen inside the weapon's sprite.

Since the effect works by copying adjacent pixels inside the framebuffer memory, the edges of the game view become a problem. When drawing the effect on the topmost row of the game view it is obviously not possible to copy pixels from one row above and likewise, at the bottommost row it is not possible to copy pixels from one row below. For this reason, the original engine always keeps a gap of one pixel on the top and bottom edges of the view where the fuzz effect is disabled. This is most easily noticed when the player has become partially invisible and their own weapon's sprite becomes affected by the fuzz effect: there is always a gap between the player's weapon and the bottom of the view. This happens even if fullscreen mode is not used; the gap then appears between the player's weapon and the status bar or the screen border fill. Without this limitation, the code responsible for drawing the fuzz effect would try to copy pixels from outside the game view. This would cause either the status bar or the screen border fill to bleed into the game view or, if the view size is large enough, garbage from outside the screen area would bleed into the game view. In the worst case, the game could crash due to invalid memory accesses.

Some source ports in the past attempted to overcome this limitation by changing the fuzz table so that pixels are copied horizontally instead of vertically, but this approach still has the issue, merely shifting it from the top and bottom edges of the view to the left and right edges. With this modification, and without disabling fuzz drawing for the leftmost and rightmost columns of the game view, partially invisible things drawn near the left or right edges will cause pixels to bleed from the opposite edge of the game view or, if the game view width is set below the maximum, the screen border fill bleeds into the game view.

Stippling effect[edit]

The characteristic stippling effect in partially invisible objects is due to a result of the algorithm's behavior which could be considered a bug. The algorithm works by going down each column of the sprite from top to bottom, copying the color value from the background pixel immediately above or below the current pixel, and then slightly darkening the color value by applying a new colormap to it. The result of this behavior is that when the algorithm has a series of pixels where each one is copied from the one above it, as often occurs, the original color copied into the first pixel in the series is repeatedly copied and darkened in the succeeding pixels until it becomes nearly black. Due to the subtle nature of this behavior, which displays a degree of hysteresis arising from a positive feedback loop, it seems likely that it was not intentional.

Animation remains still[edit]

When the screen size is changed, it creates different motions and different patterns that repeat themselves on the player's partially invisible weapon. It may occur that at a certain screen size that the effect's motion stops. This is the case when the screen's size (referred as screenblocks in the game's configuration file) is set to the default border size (which is 9; the game draws a one block thick border) and that the selected weapon is the shotgun. If the player is immobile, the fuzz effect will stop its motion completely. Since the fuzz effect was designed to create a motion of darkened pixels, this is considered a bug. Because this bug depends on the weapon's sprite shape, it may occur when custom WADs that change the weapons are used. This bug is fixed in source ports in which the code to create the fuzz effect was rewritten, such as Doom Retro, while it is exacerbated in some others, such as ZDoom, due to differences in screen sizes and the availability of higher resolution rendering.

Appearance in source ports and console ports[edit]

Due to differences in rendering technology, several source ports – especially those based on hardware accelerated 3D APIs like Direct3D and OpenGL – use translucency in place of the fuzz effect. The appearance of partially invisible monsters is not uniform among such ports: some simply use the sprite of the base monster (i.e. the demon for the spectre) with reduced opacity, some also darken the sprite in addition to reduced opacity, and some apply an animated "noise" texture to approximate the stippling of the original.

Rendering translucent objects both correctly and efficiently is not a trivial task for a 3D engine. The often used Z-buffer feature only works correctly for "binary alpha" (either completely opaque or completely transparent texels). A correct display of translucent objects may require several rendering passes with different attributes (especially respecting or ignoring the Z-buffer) in a specific order to display partially covered or intersecting translucent objects without noticeable artifacts, which can slow down the rendering speed. This order may even change for dead monsters, so it is possible to see through blood splats on the floor and walls where they are covered by a translucent spectre corpse, depending on the specific 3D renderer and port.

The issue is also observed in console ports of Doom. Certain versions, such as the Atari Jaguar, Sega 32X, and Game Boy Advance releases, do not render the fuzz effect on spectres and lack the partial invisibility powerup, which speaks to the difficulty of rendering this effect. Some console ports render the effect through translucency, and the GBA version of Doom II renders the effect quite similarly to the PC version, although still not identically. In Doom 64, some partially invisible monsters become completely visible when killed.

See also[edit]