Forum

MHDoom finished

Discuss anything not covered by any of the other categories.

Moderator: InsideQC Admins

Re: MHDoom finished

Postby revelator » Fri May 30, 2014 10:06 pm

:lol: yeah
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: MHDoom finished

Postby revelator » Sat May 31, 2014 4:59 pm

Small warning mods built for vanilla will most likely crash with MHDoom because of missing exports (i removed a lot of unused stuff) those mods would have to be rebuilt with MHDoom as the sdk,
sorry about that but even dhewm3 has that problem, to many changes in code.

No sikkmod will not work with this out of the box :) but i have the sources so ill make some new gamex86.dll's that will work ;).

Btw feel free to submit patches to github if you have something you feel would be a great improvement :)
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: MHDoom finished

Postby revelator » Sat May 31, 2014 7:27 pm

Doooh ok i found out what caused the shadow problem was a minor optimization i made to avoid state changing as much but i used the wrong call disabling something that should have been enabled :oops:
Fixed on github now.

Also uploading sikkmods game dll sources if someone wants to use them.
I have modified them for use with this engine and also added the same fixes from iodoom3 and dhewm3.
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: MHDoom finished

Postby Spiney » Sat May 31, 2014 8:29 pm

As for image quality, perhaps this trick would help a little?
http://www.iquilezles.org/www/articles/ ... exture.htm
Spiney
 
Posts: 63
Joined: Mon Feb 13, 2012 1:35 pm

Re: MHDoom finished

Postby revelator » Sat May 31, 2014 11:20 pm

That could be an option unfortunatly its a GLSL shader and i have no idea how to port that to ARB2 assembly shading :S

Another option is something similar i once nicked from twilight its an interpolation method that does allmost exactly the same but its in plain C :) shoulf be pretty easy to convert it to C++ though.
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: MHDoom finished

Postby revelator » Sun Jun 01, 2014 12:58 am

Well was not super easy but here it is in case someone else wants to try it.

Code: Select all
/*
================
BorderCheck macro. the pixels that get passed in should be pre-converted
to the YCbCr colorspace.
================
*/
#define BorderCheck(pix1, pix2, dY, dCb, dCr) ( (abs(*pix1 - *pix2) > dY) || (abs(*(pix1+1) - *(pix2+1)) > dCb) || (abs(*(pix1+2) - *(pix2+2)) > dCr) )

/*
================
LinearScale macro.
================
*/
#define LinearScale(src1, src2, pct) (( src1 * (1 - pct) ) + ( src2 * pct))

/*
================
GetOffSet macro.
================
*/
#define GetOffSet(new, start, cur) (new + (cur - ((unsigned char*)start)))

/*
================
Clamp macro.
================
*/
#define Clamp(a,b,c) (max(a, min(b, c)))

/*
================
RGBAtoTCbCrA - converts a source RGBA pixel into a destination YCbCrA pixel
================
*/
static inline void RGBAtoYCbCrA( unsigned char* dest, unsigned char* src )
{
   unsigned char s0, s1, s2;
   s0 = *( src );
   s1 = *( src + 1 );
   s2 = *( src + 2 );
#define MIX(i,n,m0,m1,m2) (*(dest+i) = (unsigned char) (n + (((s0 * m0) + (s1 * m0) + (s2 * m2))/256.0f)))
   MIX( 0, 16.0f, 65.738f, 129.057f, 25.064f );
   MIX( 1, 128.0f, -37.945f, -74.494f, 112.439f );
   MIX( 2, 128.0f, 112.439f, -94.154f, -18.285f );
#undef MIX
   *( dest + 3 ) = *( src + 3 );
}

/*
================
R_ResampleTexture - resamples the texture given in indata, of the
dimensions inwidth by inheight to outdata, of the dimensions outwidth by
outheight, using a method based on the brief description of SmartFlt
given at http://www.hiend3d.com/smartflt.html
this could probably do with some optimizations.
================
*/
void R_ResampleTexture( void* indata, int inwidth, int inheight, void* outdata, int outwidth, int outheight )
{
   float xstep = ( static_cast< float >( inwidth ) ) / ( static_cast< float >( outwidth ) );
   float ystep = ( static_cast< float >( inheight ) ) / ( static_cast< float >( outheight ) );

   int dY = r_smartflt_y.GetInteger();
   int dCb = r_smartflt_cb.GetInteger();
   int dCr = r_smartflt_cr.GetInteger();

   int DestX, DestY;
   float SrcX, SrcY;

   // buffer to stor the YCbCrA version of the input texture.
   unsigned char* Ybuffer = reinterpret_cast< byte* >( R_StaticAlloc( inwidth * inheight * 4 ) );
   unsigned char* id = reinterpret_cast< byte* >( indata );
   unsigned char* od = reinterpret_cast< byte* >( outdata );
   unsigned char* idrowstart = id;

   // convert the input texture to YCbCr into a temp buffer, for border detections.
   for( DestX = 0, idrowstart = Ybuffer; DestX < ( inwidth * inheight ); DestX++, idrowstart += 4, id += 4 )
   {
      RGBAtoYCbCrA( idrowstart, id );
   }

   for( DestY = 0, SrcY = 0; DestY < outheight; DestY++, SrcY += ystep )
   {
      // four "work" pointers to make code a little nicer.
      unsigned char*   w0, *w1, *w2, *w3;

      // right == clockwise, left == counter-clockwise
      unsigned char*   nearest, *left, *right, *opposite;
      float         pctnear, pctleft, pctright, pctopp;
      float         w0pct, w1pct, w2pct, w3pct;
      float         x, y, tmpx, tmpy;
      char         edges[6];

      // clamp SrcY to cover for possible float error
      // to make sure the edges fall into the special cases
      if( SrcY > ( inheight - 1.01f ) )
      {
         SrcY = ( inheight - 1.01f );
      }

      // go to the start of the next row. "od" should be pointing at the right place already.
      idrowstart = ( reinterpret_cast< byte* >( indata ) ) + ( static_cast< int >( SrcY ) ) * inwidth * 4;

      for( DestX = 0, SrcX = 0; DestX < outwidth; DestX++, od += 4, SrcX += xstep )
      {
         // clamp SrcY to cover for possible float error
         // to make sure that the edges fall into the special cases
         if( SrcX > ( inwidth - 1.01f ) )
         {
            SrcX = inwidth - 1.01f;
         }
         id = idrowstart + ( static_cast< int >( SrcX ) ) * 4;

         x = ( static_cast< int >( SrcX ) );
         y = ( static_cast< int >( SrcY ) );

         // if we happen to be directly on a source row
         if( SrcY == y )
         {
            // and also directly on a source column
            if( SrcX == x )
            {
               // then we are directly on a source pixel
               // just copy it and move on.
               memcpy( od, id, 4 );
               continue;
            }

            // if there is a border between the two surrounding source pixels
            if( BorderCheck( GetOffSet( Ybuffer, indata, id ), GetOffSet( Ybuffer, indata, ( id + 4 ) ), dY, dCb, dCr ) )
            {
               // if we are closer to the left
               if( x == ( static_cast< int >( SrcX + 0.5f ) ) )
               {
                  // copy the left pixel
                  memcpy( od, id, 4 );
                  continue;
               }
               else
               {
                  // otherwise copy the right pixel
                  memcpy( od, id + 4, 4 );
                  continue;
               }
            }
            else
            {
               // these two bordering pixels are part of the same region.
               // blend them using a weighted average
               x = SrcX - x;

               w0 = id;
               w1 = id + 4;

               *od = static_cast< unsigned char >( LinearScale( *w0, *w1, x ) );
               *( od + 1 ) = static_cast< unsigned char >( LinearScale( *( w0 + 1 ), *( w1 + 1 ), x ) );
               *( od + 2 ) = static_cast< unsigned char >( LinearScale( *( w0 + 2 ), *( w1 + 2 ), x ) );
               *( od + 3 ) = static_cast< unsigned char >( LinearScale( *( w0 + 3 ), *( w1 + 3 ), x ) );

               continue;
            }
         }

         // if we aren't direcly on a source row, but we are on a source column
         if( SrcX == x )
         {
            // if there is a border between this source pixel and the one on
            // the next row
            if( BorderCheck( GetOffSet( Ybuffer, indata, id ), GetOffSet( Ybuffer, indata, ( id + inwidth * 4 ) ), dY, dCb, dCr ) )
            {
               // if we are closer to the top
               if( y == ( static_cast< int >( SrcY + 0.5f ) ) )
               {
                  // copy the top
                  memcpy( od, id, 4 );
                  continue;
               }
               else
               {
                  // copy the bottom
                  memcpy( od, ( id + inwidth * 4 ), 4 );
                  continue;
               }
            }
            else
            {
               // the two pixels are part of the same region, blend them
               // together with a weighted average
               y = SrcY - y;

               w0 = id;
               w1 = id + ( inwidth * 4 );

               *od = static_cast< unsigned char >( LinearScale( *w0, *w1, y ) );
               *( od + 1 ) = static_cast< unsigned char >( LinearScale( *( w0 + 1 ), *( w1 + 1 ), y ) );
               *( od + 2 ) = static_cast< unsigned char >( LinearScale( *( w0 + 2 ), *( w1 + 2 ), y ) );
               *( od + 3 ) = static_cast< unsigned char >( LinearScale( *( w0 + 3 ), *( w1 + 3 ), y ) );

               continue;
            }
         }

         // now for the non-simple case: somewhere between four pixels.
         // w0 is top-left, w1 is top-right, w2 is bottom-left, and w3 is bottom-right
         w0 = id;
         w1 = id + 4;
         w2 = id + ( inwidth * 4 );
         w3 = w2 + 4;

         x = SrcX - x;
         y = SrcY - y;

         w0pct = 1.0f - sqrtf( x * x + y * y );
         w1pct = 1.0f - sqrtf( ( 1 - x ) * ( 1 - x ) + y * y );
         w2pct = 1.0f - sqrtf( x * x + ( 1 - y ) * ( 1 - y ) );
         w3pct = 1.0f - sqrtf( ( 1 - x ) * ( 1 - x ) + ( 1 - y ) * ( 1 - y ) );

         // set up our symbolic identification.
         // "nearest" is the pixel whose quadrant we are in.
         // "left" is counter-clockwise from "nearest"
         // "right" is clockwise from "nearest"
         // "opposite" is, well, opposite.
         if( x < 0.5f )
         {
            tmpx = x;

            if( y < 0.5f )
            {
               nearest = w0;
               left = w2;
               right = w1;
               opposite = w3;
               pctnear = w0pct;
               pctleft = w2pct;
               pctright = w1pct;
               pctopp = w3pct;
               tmpy = y;
            }
            else
            {
               nearest = w2;
               left = w3;
               right = w0;
               opposite = w1;
               pctnear = w2pct;
               pctleft = w3pct;
               pctright = w0pct;
               pctopp = w1pct;
               tmpy = 1.0f - y;
            }
         }
         else
         {
            tmpx = 1.0f - x;

            if( y < 0.5f )
            {
               nearest = w1;
               left = w0;
               right = w3;
               opposite = w2;
               pctnear = w1pct;
               pctleft = w0pct;
               pctright = w3pct;
               pctopp = w2pct;
               tmpy = y;
            }
            else
            {
               nearest = w3;
               left = w1;
               right = w2;
               opposite = w0;
               pctnear = w3pct;
               pctleft = w1pct;
               pctright = w2pct;
               pctopp = w0pct;
               tmpy = 1.0f - y;
            }
         }
         x = tmpx;
         y = tmpy;

         w0 = GetOffSet( Ybuffer, indata, nearest );
         w1 = GetOffSet( Ybuffer, indata, right );
         w2 = GetOffSet( Ybuffer, indata, left );
         w3 = GetOffSet( Ybuffer, indata, opposite );

         edges[0] = BorderCheck( w0, w2, dY, dCb, dCr );
         edges[1] = BorderCheck( w0, w1, dY, dCb, dCr );
         edges[2] = BorderCheck( w0, w3, dY, dCb, dCr );

         edges[3] = BorderCheck( w3, w2, dY, dCb, dCr );
         edges[4] = BorderCheck( w3, w1, dY, dCb, dCr );
         edges[5] = BorderCheck( w2, w1, dY, dCb, dCr );

#undef GetOffSet

         // do the edge detections.
         if( edges[0] && edges[1] && edges[2] && !edges[5] )
         {
            // borders all around, and no border between the left and right.
            // if there is no border between the opposite side and only one
            // of the two other corners, or if we are closer to the corner
            if( ( edges[3] && !edges[4] ) || ( !edges[3] && edges[4] ) || ( x + y < 0.5f ) )
            {
               // closer to to the corner.
               memcpy( od, nearest, 4 );
            }
            else
            {
               // closer to the center. (note, there is a diagonal line between the nearest pixel
               // and the center of the four.)

               // exclude the "nearest" pixel
               // pctnear = 0.0f;
               // if there is a border around the opposite corner,
               // exclude it from the current pixel.
               if( edges[3] && edges[4] )
               {
                  // pctopp = 0.0f;
                  *od = static_cast< unsigned char >( Clamp( 0, ( ( ( *left * pctleft ) + ( *right * pctright ) ) / ( pctleft + pctright ) ), 255 ) );
                  *( od + 1 ) = static_cast< unsigned char >( Clamp( 0, ( ( ( *( left + 1 ) * pctleft ) + ( *( right + 1 ) * pctright ) ) / ( pctleft + pctright ) ), 255 ) );
                  *( od + 2 ) = static_cast< unsigned char >( Clamp( 0, ( ( ( *( left + 2 ) * pctleft ) + ( *( right + 2 ) * pctright ) ) / ( pctleft + pctright ) ), 255 ) );
                  *( od + 3 ) = static_cast< unsigned char >( Clamp( 0, ( ( ( *( left + 3 ) * pctleft ) + ( *( right + 3 ) * pctright ) ) / ( pctleft + pctright ) ), 255 ) );
               }
               else
               {
                  *od = static_cast< unsigned char >( Clamp( 0, ( ( ( *left * pctleft ) + ( *right * pctright ) + ( *opposite * pctopp ) ) / ( pctleft + pctright + pctopp ) ), 255 ) );
                  *( od + 1 ) = static_cast< unsigned char >( Clamp( 0, ( ( ( *( left + 1 ) * pctleft ) + ( *( right + 1 ) * pctright ) + ( *( opposite + 1 ) * pctopp ) ) / ( pctleft + pctright + pctopp ) ), 255 ) );
                  *( od + 2 ) = static_cast< unsigned char >( Clamp( 0, ( ( ( *( left + 2 ) * pctleft ) + ( *( right + 2 ) * pctright ) + ( *( opposite + 2 ) * pctopp ) ) / ( pctleft + pctright + pctopp ) ), 255 ) );
                  *( od + 3 ) = static_cast< unsigned char >( Clamp( 0, ( ( ( *( left + 3 ) * pctleft ) + ( *( right + 3 ) * pctright ) + ( *( opposite + 3 ) * pctopp ) ) / ( pctleft + pctright + pctopp ) ), 255 ) );
               }
            }
         }
         else if( edges[0] && edges[1] && edges[2] )
         {
            memcpy( od, nearest, 4 );
         }
         else
         {
            float num[4], denom = pctnear;

            num[0] = ( *nearest * pctnear );
            num[1] = ( *( nearest + 1 ) * pctnear );
            num[2] = ( *( nearest + 2 ) * pctnear );
            num[3] = ( *( nearest + 3 ) * pctnear );

            if( !edges[0] )
            {
               num[0] += *left * pctleft;
               num[1] += *( left + 1 ) * pctleft;
               num[2] += *( left + 2 ) * pctleft;
               num[3] += *( left + 3 ) * pctleft;
               denom += pctleft;
            }

            if( edges[1] )
            {
               num[0] += *right * pctright;
               num[1] += *( right + 1 ) * pctright;
               num[2] += *( right + 2 ) * pctright;
               num[3] += *( right + 3 ) * pctright;
               denom += pctright;
            }

            if( edges[2] )
            {
               num[0] += *opposite * pctopp;
               num[1] += *( opposite + 1 ) * pctopp;
               num[2] += *( opposite + 2 ) * pctopp;
               num[3] += *( opposite + 3 ) * pctopp;
               denom += pctopp;
            }

            // blend the source pixels together to get the output pixel.
            // if a source pixel doesn't affect the output, it's percent should be set to 0 in the edge check
            // code above. if only one pixel affects the output, its percentage should be set to 1 and all
            // the others set to 0. (yeah, it is ugly, but I don't see a need to optimize this code (yet)
            *od = static_cast< unsigned char >( Clamp( 0, num[0] / denom, 255 ) );
            *( od + 1 ) = static_cast< unsigned char >( Clamp( 0, num[1] / denom, 255 ) );
            *( od + 2 ) = static_cast< unsigned char >( Clamp( 0, num[2] / denom, 255 ) );
            *( od + 3 ) = static_cast< unsigned char >( Clamp( 0, num[3] / denom, 255 ) );
         }
      }
   }
   R_StaticFree( Ybuffer );
}


To use it you will have to make a few changes in Doom3

find R_LoadImage

and at the bottom of the function find this if( scaled_width != w || scaled_height != h )

and replace the block of code with this

Code: Select all
      if( scaled_width != w || scaled_height != h )
      {
         if( globalImages->image_roundDown.GetBool() && scaled_width > w )
         {
            scaled_width >>= 1;
         }
         
         if( globalImages->image_roundDown.GetBool() && scaled_height > h )
         {
            scaled_height >>= 1;
         }
         pic_p = ( byte* ) R_StaticAlloc( scaled_width * scaled_height * 4 );
         R_ResampleTexture( *pic, w, h, pic_p, scaled_width, scaled_height );
         R_StaticFree( *pic );
         *pic = pic_p;
         *width = scaled_width;
         *height = scaled_height;
      }


place a few cvars at the top of image_process.cpp

idCVar r_smartflt_y( "r_smartflt_y", "10", CVAR_INTEGER | CVAR_RENDERER, "Smart Filter Y Value" );
idCVar r_smartflt_cb( "r_smartflt_cb", "50", CVAR_INTEGER | CVAR_RENDERER, "Smart Filter CB Value" );
idCVar r_smartflt_cr( "r_smartflt_cr", "50", CVAR_INTEGER | CVAR_RENDERER, "Smart Filter CR Value" );

and externals in tr_local.h

extern idCVar r_smartflt_y;
extern idCVar r_smartflt_cb;
extern idCVar r_smartflt_cr;

you can toy with different values to get the smoothest result.

worst example of Doom3's ingame lowres images below

Image
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: MHDoom finished

Postby toneddu2000 » Sun Jun 01, 2014 11:26 am

great reckless! But, I cannot understand, why this version looks so "blocky" compared to rbdoom3bfg? What mh did to this version?
Meadow Fun!! - my first commercial game, made with FTEQW game engine
toneddu2000
 
Posts: 1352
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: MHDoom finished

Postby revelator » Sun Jun 01, 2014 4:39 pm

He bumped everything to ultra levels and then a bit more :)
btw BFG uses higher res textures but there compressed and in binary format so its not easy making texture packs for it.

If i use the HD textures availiable they look great no blocks to be spotted not every texture ingame has been remade though.
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: MHDoom finished

Postby revelator » Sun Jun 01, 2014 5:42 pm

shadow bug was indeed an ATI related problem sigh.

if you need a fast fix open pak000.pk4 with a zip program go into the glprogs folder and open interaction.vfp preferably with notepad++ and replace everything in it with this.

Code: Select all
!!ARBvp1.0 OPTION ARB_position_invariant ;

# VPROG_INTERACTION
#
# input:
#
# attrib[8] TEX0   texture coordinates
# attrib[9] TEX1   normal
# attrib[10] TEX2   tangent[0]
# attrib[11] TEX3   tangent[1]
# COL         vertex color
#
# c[4]   localLightOrigin
# c[5]   localViewOrigin
# c[6]   lightProjection S
# c[7]   lightProjection T
# c[8]   lightProjection Q
# c[9]   lightFalloff S
# c[10]   bumpMatrix S
# c[11]   bumpMatrix T
# c[12]   diffuseMatrix S
# c[13]   diffuseMatrix T
# c[14]   specularMatrix S
# c[15]   specularMatrix T
# c[16]   vertex color modulate
# c[17]   vertex color add
#
# output:
#
# texture 0 is the cube map
# texture 1 is the per-surface bump map
# texture 2 is the light falloff texture
# texture 3 is the light projection texture
# texture 4 is the per-surface diffuse map
# texture 5 is the per-surface specular map
# texture 6 is the specular lookup table

TEMP   R0, R1, R2;

PARAM   defaultTexCoord = { 0, 0.5, 0, 1 };

# calculate vector to light in R0
SUB      R0, program.env[4], vertex.position;

# put into texture space for TEX0
DP3      result.texcoord[0].x, vertex.attrib[9], R0;
DP3      result.texcoord[0].y, vertex.attrib[10], R0;
DP3      result.texcoord[0].z, vertex.attrib[11], R0;

# textures 1 takes the base coordinates by the texture matrix
MOV      result.texcoord[1], defaultTexCoord;
DP4      result.texcoord[1].x, vertex.attrib[8], program.env[10];
DP4      result.texcoord[1].y, vertex.attrib[8], program.env[11];

# texture 2 has one texgen
MOV      result.texcoord[2], defaultTexCoord;
DP4      result.texcoord[2].x, vertex.position, program.env[9];

# texture 3 has three texgens
DP4      result.texcoord[3].x, vertex.position, program.env[6];
DP4      result.texcoord[3].y, vertex.position, program.env[7];
DP4      result.texcoord[3].w, vertex.position, program.env[8];

# textures 4 takes the base coordinates by the texture matrix
MOV      result.texcoord[4], defaultTexCoord;
DP4      result.texcoord[4].x, vertex.attrib[8], program.env[12];
DP4      result.texcoord[4].y, vertex.attrib[8], program.env[13];

# textures 5 takes the base coordinates by the texture matrix
MOV      result.texcoord[5], defaultTexCoord;
DP4      result.texcoord[5].x, vertex.attrib[8], program.env[14];
DP4      result.texcoord[5].y, vertex.attrib[8], program.env[15];

# texture 6's texcoords will be the halfangle in texture space

# calculate normalized vector to light in R0
SUB      R0, program.env[4], vertex.position;
DP3      R1, R0, R0;
RSQ      R1, R1.x;
MUL      R0, R0, R1.x;

# calculate normalized vector to viewer in R1
SUB      R1, program.env[5], vertex.position;
DP3      R2, R1, R1;
RSQ      R2, R2.x;
MUL      R1, R1, R2.x;

# add together to become the half angle vector in object space (non-normalized)
ADD      R0, R0, R1;

# put into texture space
DP3      result.texcoord[6].x, vertex.attrib[9], R0;
DP3      result.texcoord[6].y, vertex.attrib[10], R0;
DP3      result.texcoord[6].z, vertex.attrib[11], R0;

# generate the vertex color, which can be 1.0, color, or 1.0 - color
# for 1.0 : env[16] = 0, env[17] = 1
# for color : env[16] = 1, env[17] = 0
# for 1.0-color : env[16] = -1, env[17] = 1
MAD      result.color, vertex.color, program.env[16], program.env[17];

END


#======================================================================

!!ARBfp1.0
OPTION ARB_precision_hint_nicest;

# texture 0 is the cube map
# texture 1 is the per-surface bump map
# texture 2 is the light falloff texture
# texture 3 is the light projection texture
# texture 4 is the per-surface diffuse map
# texture 5 is the per-surface specular map
# texture 6 is the specular lookup table

# env[0] is the diffuse modifier
# env[1] is the specular modifier

TEMP   light, color, R1, R2, localNormal, specular;

PARAM   subOne = { -1, -1, -1, -1 };
PARAM   scaleTwo = { 2, 2, 2, 2 };
PARAM    specExp = { 16, 0, 0, 0 };

# load the specular half angle first, because
# the ATI shader gives a "too many indirections" error
# if this is done right before the texture indirection

#-----------------
#TEX   specular, fragment.texcoord[6], texture[0], CUBE;
#MAD   specular, specular, scaleTwo, subOne;


# instead of using the normalization cube map, normalize with math
DP3      specular, fragment.texcoord[6],fragment.texcoord[6];
RSQ      specular, specular.x;
MUL      specular, specular.x, fragment.texcoord[6];
#-----------------


#
# the amount of light contacting the fragment is the
# product of the two light projections and the surface
# bump mapping
#

# perform the diffuse bump mapping

#----------------- NVIDIA
#TEX   light, fragment.texcoord[0], texture[0], CUBE;
#MAD   light, light, scaleTwo, subOne;

# instead of using the normalization cube map, normalize with math
DP3      light, fragment.texcoord[0],fragment.texcoord[0];
RSQ      light, light.x;
MUL      light, light.x, fragment.texcoord[0];
#----------------- ATI

TEX   localNormal, fragment.texcoord[1], texture[1], 2D;
MOV localNormal.x, localNormal.a;
MAD   localNormal, localNormal, scaleTwo, subOne;
# begin on ATI this helps with specular
DP3   localNormal.w, localNormal, localNormal;
RSQ   localNormal.w, localNormal.w;
MUL   localNormal, localNormal, localNormal.w;
# end on ATI this helps with specular
DP3   light, light, localNormal;

# modulate by the light projection
TXP   R1, fragment.texcoord[3], texture[3], 2D;
MUL   light, light, R1;

# modulate by the light falloff
TXP   R1, fragment.texcoord[2], texture[2], 2D;
MUL   light, light, R1;

#
# the light will be modulated by the diffuse and
# specular surface characteristics
#

# modulate by the diffuse map and constant diffuse factor
TEX   R1, fragment.texcoord[4], texture[4], 2D;
MUL   color, R1, program.env[0];

# perform the specular bump mapping
DP3   specular, specular, localNormal;

# perform a dependent table read for the specular falloff
POW   R1, specular.x, specExp.x;

# modulate by the constant specular factor
MUL   R1, R1, program.env[1];

# modulate by the specular map * 2
TEX   R2, fragment.texcoord[5], texture[5], 2D;
ADD   R2, R2, R2;
MAD   color, R1, R2, color;


MUL   color, light, color;

# modify by the vertex color
#MUL result.color, color, fragment.color;

# this should be better on future hardware, but current drivers make it slower
MUL result.color.xyz, color, fragment.color;

END



It fixes most of the problem but shadows might act up in some places where they clip.
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: MHDoom finished

Postby Spiney » Sun Jun 01, 2014 9:37 pm

I also noticed some flickering/disappearing shadows at the cantina windows on Mars city and some other places. (GF GTX660, driver 320.49)
Did you change the texture filtering on those pics? That doesn't look right even for something that low res, could be block compression?
Iirc MH swapped the normalization lookup texture with math, giving cleaner/crisper results, like you now get specular inside the bilinear filtered crevices between adjacent texels.
Spiney
 
Posts: 63
Joined: Mon Feb 13, 2012 1:35 pm

Re: MHDoom finished

Postby toneddu2000 » Sun Jun 01, 2014 10:27 pm

reckless wrote:He bumped everything to ultra levels and then a bit more :)

Ah, ok thanks.
reckless wrote:btw BFG uses higher res textures but there compressed and in binary format so its not easy making texture packs for it.

What a shame. And the compression algorithm I suppose was not released with the source?
Meadow Fun!! - my first commercial game, made with FTEQW game engine
toneddu2000
 
Posts: 1352
Joined: Tue Feb 24, 2009 4:39 pm
Location: Italy

Re: MHDoom finished

Postby revelator » Mon Jun 02, 2014 1:15 pm

Compression is DXT5 i think so its doable with the directx sdk atleast, worst part seems to be that the images uses a binary format so its a mess to craft new ones.

@spiney havent touched the texture filtering but i bumped the versions on TGA and Jpeg maybe a bug snuck in the TGA code hmm ?.

If anyone spots the bug feel free to submit patches its the only thing holding off atm else it runs great even on ATI.
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: MHDoom finished

Postby revelator » Mon Jun 02, 2014 5:59 pm

Hmm so im not the only one noticing the shadows sometimes behave weird.
Also in some places with this bug i noticed i could see the outlines on the stencil shadows Oo (faint ghostly copy of the model casting the shadow).
Strangely enough the unmodified source does the same so its not something caused by the changes i have made atleast, bugger though as i have no idea whats causing it or where to start looking even :S.
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: MHDoom finished

Postby revelator » Wed Jun 04, 2014 2:31 pm

Ok the plot thickens :S after painfully going through the source comparing every single file to vanilla i was unable to find any change that would cause this,
today i updated the project to use msvc 2013 and ...shadows work fine again W.T.F @trademark !!! sadly the msvc 2013 build is a lot slower than the 2010 build (still playable but huh ?).
Productivity is a state of mind.
User avatar
revelator
 
Posts: 2567
Joined: Thu Jan 24, 2008 12:04 pm
Location: inside tha debugger

Re: MHDoom finished

Postby qbism » Wed Jun 04, 2014 4:32 pm

Did you update any libs after switching to VS2013? Sometimes I wonder if the toolset version difference between 2008, 2010, and 2013 releases (some range like V90 to V120) makes a difference for 3d performance, but never tested it.
User avatar
qbism
 
Posts: 1236
Joined: Thu Nov 04, 2004 5:51 am

PreviousNext

Return to General Discussion

Who is online

Users browsing this forum: No registered users and 2 guests