Partial invisibility effect



Partial invisibility effect (also known as the fuzz effect) is a visual effect which is used in Doom for Spectres and for the Partial invisibility player powerup, though replaced by true or table-based translucency in some source ports. The engine is technically capable of applying the effect to any arbitrary thing, but by default it is only used for the aforementioned. Heretic, Hexen and Strife do not use this effect at all, relying on translucency instead.

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

Vertical cutoff
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, when drawing the effect on the bottommost row of the game view 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 picked up the partial invisibility powerup and their own weapon's sprite becomes affected by the fuzz effect: there is always a gap of one pixel 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 bleed into the game view or, if the view size is large enough, it would cause garbage from outside the screen area bleed into the game view. In the worst case, the game could even crash due to invalid memory accesses.

Some source ports in the past have 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 same issue: it just moves the problem 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 that are being 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, they will cause the screen border fill to bleed into the game view.

Different appearance in source ports
Due to a different rendering technology, several source ports – especially those based on hardware accellerated 3D APIs like Direct3D and OpenGL – do not use the fuzzing effect but use translucency = reduced opacity for the used sprites or mesh based models. The texturing of partially invisible monsters is not uniform among the different ports either: Some simply use the texture of the base monster (i.e. the Demon for the Spectre), some apply an animated noisy texture to get closer to the original fuzzing effect. It is also not uniform if killed partially visible monsters become completely visible after death (which happens for some monsters in Doom 64 source ports).

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 and even intersecting translucent objects without noticable artifacts, which can slow down the rendering speed. This order may 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 corpse of a Spectre – depending on the specific 3D engine and source port.