Game Development Community

HOWTO: Add new material properties

by Dan Keller · in Torque Game Engine Advanced · 12/15/2008 (7:23 pm) · 1 replies

After going through the hassle of figuring this out myself, I decided to make a short write-up on how to add properties to standard materials, using a simple example. This tutorial describes how to add a property that controls overall texture scale per pass.

Overall there are 10 files that need changes, most quite minor.

* material.h
* shdrConsts.h (both copies)
* gfxStructs.h
* processedMaterial.h
* shaderFeature.h
* material.cpp
* shaderFeature.cpp
* featureMgr.cpp
* processedShaderMaterial.cpp


Add the bold code to the following files:

material.h
ColorF            colorMultiply[MAX_STAGES];
   [b]F32            scaleFactor[MAX_STAGES];[/b]
   F32               specularPower[MAX_STAGES];

shdrConsts.h Change both the copy in the project and the one in \game\shaders
#define VC_DETAIL_SCALE    C40
[b]#define VC_SCALE_FACTOR     C41[/b]
...
#define VC_DETAIL_SCALE    40
[b]#define VC_SCALE_FACTOR     41[/b]

gfxStructs.h
ColorMultiply,
      [b]ScaleFactor,[/b]
      DynamicLight,

processedMaterial.h
Same as gfxStructs.h.

material.cpp
colorMultiply[ i ].set(0.0f, 0.0f, 0.0f, 0.0f);
      [b]scaleFactor[ i ] = 1.0f;[/b]
      specularPower[ i ] = 8;
...
   addField("colorMultiply", TypeColorF, Offset(colorMultiply, Material), MAX_STAGES);
   [b]addField("scaleFactor", TypeColorF, Offset(scaleFactor, Material), MAX_STAGES);[/b]
   addField("specular",    TypeColorF, Offset(specular,   Material), MAX_STAGES);

featureMgr.cpp
mFeatures[ GFXShaderFeatureData::ColorMultiply ] = new ColorMultiplyFeat;
  [b]mFeatures[ GFXShaderFeatureData::ScaleFactor ] = new ScaleFactorFeat;[/b]
   mFeatures[ GFXShaderFeatureData::DynamicLight ] = NULL;

processedShaderMaterial.cpp
fd.features[ i ] = true;
      }

      [b]// Texture Scaling
      if (i == GFXShaderFeatureData::ScaleFactor)
      {
         if (mMaterial->scaleFactor[stageNum] != 1.0f)
            fd.features[ i ] = true;
      }[/b]

      // These features only happen in the last state
...
   // Color multiply
   if (mMaterial->colorMultiply[stageNum].alpha > 0.0f)
   {
      GFX->setPixelShaderConstF(PC_COLORMULTIPLY, (float*)&mMaterial->colorMultiply[stageNum], 1);
   }   
[b]
   // Scale Factor
   if (mMaterial->scaleFactor[stageNum] != 1.0f)
   {
      GFX->setVertexShaderConstF(VC_SCALE_FACTOR, (float*)&mMaterial->scaleFactor[stageNum], 1);
   }[/b]  
}

shaderFeature.h
[b]
//**************************************************************************
/// ScaleFactor
//**************************************************************************
class ScaleFactorFeat : public ShaderFeature
{
public:
   virtual void processVert( Vector<ShaderComponent*> &componentList,
                             GFXShaderFeatureData &fd );

};[/b]

#endif _SHADERFEATURE_H_

shaderFeature.cpp (At the end)
void ScaleFactorFeat::processVert( Vector<ShaderComponent*> &componentList,
                                                       GFXShaderFeatureData &fd )
{
	Var *scaleFactor = new Var;
	scaleFactor->setType("float");
	scaleFactor->setName("scaleFactor");
   scaleFactor->uniform = true;
   scaleFactor->constNum = VC_SCALE_FACTOR;

	// search for tex coords
   Var *tc = (Var*) LangElement::find( "outTexCoord" );
   if (tc)
   {
      MultiLine* meta = new MultiLine;
      meta->addStatement(new GenOp("   @ = @ * @;\r\n", tc, tc, scaleFactor));
      output = meta;
   }
}


To use, just add
scaleFactor[0] = #;
to your material. Higher values make the texture smaller.

#1
12/27/2008 (12:17 pm)
Dan, very helpful. You should consider adding this as a resource.