Game Development Community

Material texture animation problems.

by Bill Vee · in Torque Game Engine Advanced · 08/29/2007 (3:16 pm) · 2 replies

Ok first consider this code
new Material(jupitermap_tex)
{
 mapTo = jupitermap;
 
   baseTex[0] = "jupitermap";
   animFlags[0] = $scroll;
   scrollDir[0] = "-1.0 0.0"; 
   scrollSpeed[0] = 0.00125; 

   baseTex[1] = jupiterclouds;
   animFlags[1] = $scroll;
   scrollDir[1] = "-1.0 0.0"; 
   scrollSpeed[1] = 0.125;
 };

If I read this TDN article correctly.

Quote:For instance, if you wanted a special effect where one layer would scroll in one direction and another would scroll on top of it in another direction and they are blended together, stages would be the way to do it.

The Material code I posted should make baseTex[0] scroll independent of baseTex[1].
But it won't, or atleast it won't for me.

The best I can do is change the code a little like this.

new Material(jupitermap_tex)
{
 mapTo = jupitermap;
 
   baseTex[0] = "jupitermap";
   animFlags[0] = $scroll;
   scrollDir[0] = "-1.0 0.0"; 
   scrollSpeed[0] = 0.00125; 

   baseTex[1] = jupiterclouds;
 };

Which causes the first texture to scroll under the second.
Not exactly what I wanted.
I want multiple layers moving at different rates for a more realistic effect.

After some searching through the source I found this.

void MatInstance::setTextureTransforms()
{

   [b]U32 i=0;[/b]
   MatrixF texMat( true );
   
   F32 waveOffset = getWaveOffset( i ); // offset is between 0.0 and 1.0
   
   
   // handle scroll anim type
   if(  mMaterial->animFlags[i] & Material::Scroll )
   {
      if( mMaterial->animFlags[i] & Material::Wave )
      {
         Point3F scrollOffset;
         scrollOffset.x = mMaterial->scrollDir[i].x * waveOffset;
         scrollOffset.y = mMaterial->scrollDir[i].y * waveOffset;
         scrollOffset.z = 1.0;
                         
         texMat.setColumn( 3, scrollOffset );
      }
      else
      {
         mMaterial->scrollOffset[i] += mMaterial->scrollDir[i] * 
                                       mMaterial->scrollSpeed[i] * 
                                       mMaterial->mDt;
                                       
         Point3F offset( mMaterial->scrollOffset[i].x, 
                         mMaterial->scrollOffset[i].y, 
                         1.0 );
                         
         texMat.setColumn( 3, offset );
      }

The U32 i=0; part limits the code to referencing just the first scrollspeed defined.

#1
08/29/2007 (3:26 pm)
Ok added a quick hack and got it working.
First in
void MatInstance::setTextureTransforms()
{

   U32 i=0;
  [b] i=mCurPass;[/b]

   MatrixF texMat( true );

Then in
bool MatInstance::setupPass( SceneGraphData &sgData )
{

   if( mMaterial->getType() != Material::base )
   {
      CustomMaterial *custMat = static_cast<CustomMaterial*>(mMaterial);

      // This setTexTrans nonsense is set to make sure that setTextureTransforms()
      // is called only once per material draw, not per pass
      static bool setTexTrans = false;
      [b]//if( !setTexTrans )
      //{
         //setTextureTransforms();
       //  setTexTrans = true;
     // }

       setTextureTransforms();[/b]

      if( custMat->setupPass( sgData ) )
      {
         return true;
      }
      else
      {
         setTexTrans = false;
         return false;
      }
   }

   ++mCurPass;

   // return when done with all passes
   if( mCurPass >= mPasses.size() ||
       filterGlowPasses( sgData ) ||
       sgData.refractPass )  // only custom materials support refraction for now
   {
      cleanup();
      return false;
   }

   // set alpha blend
   if( mCurPass > 0 )
   {
      GFX->setAlphaBlendEnable( true );
      mMaterial->setBlendState( mPasses[mCurPass].blendOp );
   }
   else
   {
      GFX->setAlphaBlendEnable( false );
   }

   if( mMaterial->translucent )
   {
      GFX->setAlphaBlendEnable( true );
      mMaterial->setBlendState( mMaterial->translucentBlendOp );   
      GFX->setZWriteEnable( mMaterial->translucentZWrite );
      GFX->setAlphaTestEnable( mMaterial->alphaTest );
      GFX->setAlphaRef( mMaterial->alphaRef );
      GFX->setAlphaFunc( GFXCmpGreaterEqual );
      
      // set up register combiners
      GFX->setTextureStageAlphaOp( 0, GFXTOPModulate );
      GFX->setTextureStageAlphaOp( 1, GFXTOPDisable );
      GFX->setTextureStageAlphaArg1( 0, GFXTATexture );
      GFX->setTextureStageAlphaArg2( 0, GFXTADiffuse );
   }

   // set shaders
   if( mPasses[mCurPass].shader )
   {
      mPasses[mCurPass].shader->process();
      mMaterial->setShaderConstants( sgData, mPasses[mCurPass].stageNum );
   }
   else
   {
      GFX->disableShaders();
      GFX->setTextureStageColorOp( mPasses[mCurPass].numTex, GFXTOPDisable );
   }

   setTextureStages( sgData, mCurPass );
   
  [b]// if( mCurPass == 0 )
  // {[/b]
      setTextureTransforms();

      if( mMaterial->doubleSided )
      {
         mCullMode = GFX->getCullMode();
         GFX->setCullMode( GFXCullNone );
      }
 [b] // }[/b]

   return true;
}

TGEA seems happy enough with the changes and now the textures will scroll, rotate, scale and wave independent of one another.
#2
05/15/2008 (12:18 pm)
The above hack I used for 1.0.3 will not work for 1.7.0 because of the numerous changes in Materials and CustomMaterials.

I have another hack to restore the function but I got to ask something.
Is there a reason for limiting the use of scroll , wave and rotate to the first texture?