Partial invisibility effect

From DoomWiki.org

Revision as of 15:50, 15 May 2012 by Dragonsbrethren (talk | contribs) (Cleaned this up a bit.)


Under construction icon-yellow.svgThis article or section is a stub. Please help the Doom Wiki by adding to it.
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 any 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 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

Partially invisible player sprite being cut off at the bottom in Doom II version 1.9

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 and console ports

Due to a different rendering technology, several ports – especially those based on hardware accelerated 3D APIs like Direct3D and OpenGL – do not use the fuzz effect but instead use translucency. The appearance of partially invisible monsters is not uniform among the different 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 noisy texture to get closer to the original fuzz effect. It is also not uniform if killed partially invisible monsters become completely visible after death, which happens for some monsters in Doom 64.

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 noticeable 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.

The problem is also observed with console ports of Doom, as 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, again showing 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 similar to the PC version, although still not exactly the same.

See also