"Sparkles" at the bottom of middle textures

I've been looking at the old MBF source, and something has piqued my interest. In the changelog (https://github.com/fragglet/mbf/blob/master/log_lee.txt) it mentions a fix for the "sparkles bug" ("bottom parts of middle textures have transparent sparkles which appear randomly when the player moves"). This has always bothered me, and the best I can tell, there's no source port that addresses it. A good example of this "bug" are the stray pixels that appear at the bottom of the first door you encounter in E1M1. In the log, the author speaks of how he implemented a fix and then commented it out as it caused other problems. Looking for that commented out fix in the code itself, I can't seem to find it. Am I just not seeing it? Could someone please tell me where it is? And if its not there, what would be the fix for this issue?

Share this post


Link to post

Eternity Engine's renderer, Cardboard, uses high-precision drawing to correct for this in most or all cases.

Share this post


Link to post

This looks to me like it's starting to draw the next texel of the column, which wraps around vertically. There's the same thing noticeable with textures that border nukage pools (with a green bottom and a brown top, and you can see a faint line of green pixels at the top if the texture is drawn to its full height). The big door in E1M1 has a dark line at the bottom, but is otherwise bright gray.

Share this post


Link to post

Is this the same reason why bamboo fences in greenday e4m1 look awful when the player is moving?

Share this post


Link to post

Any fix Lee may have considered for the issue was definitely removed from the source code, but he did leave behind a comment indicating he understood the source of the problem, from r_things.c starting at line 313:

void R_DrawMaskedColumn(column_t *column)
{
  int topscreen, bottomscreen;
  fixed_t basetexturemid = dc_texturemid;
  
  dc_texheight = 0; // killough 11/98

  while (column->topdelta != 0xff)
    {
      // calculate unclipped screen coordinates for post
      topscreen = sprtopscreen + spryscale*column->topdelta;
      bottomscreen = topscreen + spryscale*column->length;

      // Here's where "sparkles" come in -- killough:
      dc_yl = (topscreen+FRACUNIT-1)>>FRACBITS;
      dc_yh = (bottomscreen-1)>>FRACBITS;

      if (dc_yh >= mfloorclip[dc_x])
        dc_yh = mfloorclip[dc_x]-1;

      if (dc_yl <= mceilingclip[dc_x])
        dc_yl = mceilingclip[dc_x]+1;

      // killough 3/2/98, 3/27/98: Failsafe against overflow/crash:
      if (dc_yl <= dc_yh && dc_yh < viewheight)
        {
          dc_source = (byte *) column + 3;
          dc_texturemid = basetexturemid - (column->topdelta<<FRACBITS);

          // Drawn by either R_DrawColumn
          //  or (SHADOW) R_DrawFuzzColumn.
          colfunc();
        }
      column = (column_t *)((byte *) column + column->length + 4);
    }
  dc_texturemid = basetexturemid;
}

Share this post


Link to post

Seems like any Boom-derivative port actually has this fix in place.

Share this post


Link to post

I'd have to disagree about ports based on Boom fixing this problem. PrBoom+ still exhibits the "sparkles" under the first door in E1M1 at least.

The problem also seems to be more than just vertically repeating the textures. Consider in E1M2 the two flights of stairs that lead up to where you get the red keycard: you can get bright green pixels to appear at the bottom of each step if you angle the player just right.

While working on my own source port, I've been playing around with R_DrawColumn() and have put together a small, fugly hack which appears to actually solve the problem. I'm sure there is a much more efficient and elegant way of resolving this, but hey, I'm learning.

void R_DrawColumn(void)
{
    register int count = dc_yh - dc_yl + 1;
    register byte *dest;
    register fixed_t frac;
    register fixed_t fracstep;

    if (count <= 0)
        return;

    dest = ylookup[dc_yl] + columnofs[dc_x];

    fracstep = dc_iscale;
    frac = dc_texturemid + (dc_yl - centery) * fracstep;

    do
    {
        *dest = dc_colormap[dc_source[(frac >> FRACBITS) & 127]];
        dest += SCREENWIDTH;
        frac += fracstep;
    }
    while (--count);

    // [BH] very ugly hack to cover up the stray pixels at the bottom of some columns
    if (dc_yh - dc_yl > 0)
        if (!(((frac - fracstep) >> FRACBITS) & 7))
            *(dest - SCREENWIDTH) = *(dest - SCREENWIDTH * 2);
}

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now