Game Development Community

Enabling Alpha Effects

by James Urquhart · in Torque Game Engine Advanced · 09/26/2005 (9:48 am) · 18 replies

Hi there,

I am currently trying to re-enable the fade effects on ShapeBase objects.
However, i am a bit puzzled, as my code does not appear to be working.

FIXED: see below for details.

Now, i have added in the calls to set the override fade value in ShapeBase::renderObject, but of course, i don't quite see any fading going on :)

Does anyone have any ideas what specifically i have done wrong? Should i be using setAlphaRef()?

Thanks for any help.

#1
09/26/2005 (1:32 pm)
In engine\gfx\gfxStructs.h on line 96 change:

Fog,              // keep fog last feature

to

Fog,              // keep fog 2nd to last feature
      Visibility,       // keep visibility last feature

In engine\shaderGen\featureMgr.cpp on line 62 add:

mFeatures[ GFXShaderFeatureData::Visibility] = new VisibilityFeat;

In engine\shaderGen\shaderFeature.h on line 330 add:

//**************************************************************************
/// Visibility
//**************************************************************************
class VisibilityFeat : public ShaderFeature
{
public:
   virtual void processPix( Vector<ShaderComponent*> &componentList, 
                            GFXShaderFeatureData &fd );
};

In engine\shaderGen\shaderFeature.cpp on line 1083 add:

//----------------------------------------------------------------------------
// Process pixel shader feature
//----------------------------------------------------------------------------
void VisibilityFeat::processPix( Vector<ShaderComponent*> &componentList, 
                                   GFXShaderFeatureData &fd )
{
   // create visibility var
   Var *visibility = new Var;
   visibility->setType( "float" );
   visibility->setName( "visibility" );
   visibility->uniform = true;
   visibility->constNum = PC_VISIBILITY;

   // search for color var
   Var *color = (Var*) LangElement::find( "col" );

   if( !color )
   {
      // create color var
      color = new Var;
      color->setType( "fragout" );
      color->setName( "col" );
      color->setStructName( "OUT" );
   }
   
   output = new GenOp( "   @.w *= @;\r\n", color, visibility );
}

In example\shaders\shdrConsts.h on line 49 add:

#define PC_VISIBILITY      C8

In example\shaders\shdrConsts.h on line 100 add:

#define PC_VISIBILITY      8

In engine\materials\sceneData.h on line 44 add:

F32            visibility;

In engine\materials\sceneData.h on line 52 add:

visibility = 1.0f;

In engine\materials\material.cpp on line 306 add:

// set the visibility
   //-------------------------
   F32 visibility = sgData.visibility;
   GFX->setPixelShaderConstF( PC_VISIBILITY, (float*)&visibility, 1 );

In engine\materials\matInstance.cpp on line 209 add:

// visibility - last stage
      if( i == GFXShaderFeatureData::Visibility)
      {
         fd.features[i] = true;
      }

In engine\ts\tsMesh.h on line 121 add:

F32 visibility;

In engine\ts\tsMesh.h on line 277 add:

visibility = 1.0f;

In engine\ts\tsMesh.cpp on line 1228 in void TSMesh::setFade() add:

visibility = fadeValue;

In engine\ts\tsMesh.cpp on line 1242 in void TSMesh::clearFade() change:

//   setFade(1.0f);

to

setFade(1.0f);

In engine\ts\tsMesh.cpp on line 372 in void TSMesh::render() add:

sgData.visibility = visibility;

In engine\ts\tsMesh.cpp on line 423 in void TSMesh::render() (just above // draw) add:

if (visibility < 1.0f)
               {
                  GFX->setAlphaBlendEnable( true );
                  GFX->setSrcBlend( GFXBlendSrcAlpha );
                  GFX->setDestBlend( GFXBlendInvSrcAlpha );
                  GFX->setAlphaTestEnable( true );
                  GFX->setAlphaRef( 1 );
                  GFX->setAlphaFunc( GFXCmpGreaterEqual );
               }
#2
09/26/2005 (1:37 pm)
The line numbers might differ slightly b/c I was comparing against our internal repo instead of against TSE HEAD but they should be close.
#3
09/26/2005 (5:01 pm)
Nice one matt, using the shaders is definatly a better idea.


Here are my additions:

In engine\shaderGen\shaderFeature.cpp, change the end of VisibilityFeat::processPix so it looks like this:
if( !color )
   {
      // create color var
      color = new Var;
      color->setType( "fragout" );
      color->setName( "col" );
      color->setStructName( "OUT" );
      
      // link it to ConnectData.shading
      ConnectorStruct *connectComp = dynamic_cast<ConnectorStruct *>( componentList[C_CONNECTOR] );
      Var *inColor = connectComp->getElement( RT_COLOR );
      inColor->setName( "shading" );
      inColor->setStructName( "IN" );
      inColor->setType( "float4" );
      
      // Looks like its going to be a multiline statement
      MultiLine * meta = new MultiLine;
      meta->addStatement( new GenOp( "   @ = @;", 
                           color,
                           inColor ) );
      
      meta->addStatement( new GenOp( "   @.w *= @;\r\n",
                           color,
                           visibility ) );
      output = meta;
   } 
   else
      output = new GenOp( "   @.w *= @;\r\n", color, visibility );
(This will allow valid shaders to be generated if for some odd reason only visibility is being noted)


To get the fading working (e.g. using obj.setFade), do the following:

In engine\game\shapeBase.cpp, change ShapeBase::renderObject so it looks like this:
TSMesh::setRefract( image->sortType == SceneRenderImage::Refraction );

   // Start global fade
   TSMesh::setOverrideFade( mFadeVal );
   
   ...
   
   // End global fade
   TSMesh::setOverrideFade( 1.0 );

   GFX->setProjectionMatrix( proj );
(... is where the calls to renderImage and soon are)

In engine\ts\tsMesh.cpp,

change matt's sgData.visibility variable in TSMesh::render so it looks like this:
sgData.visibility = TSMesh::overrideFadeVal * visibility;

then change matt's if (visibility < 1.0f) line (should be just above //draw) to :
if (sgData.visibility < 1.0f)


That should be it. Try killing yourself in Joseph's starter.fps mod, and you should fade out.
(NOTE: you might need to change Player::renderImage as well, although fading should be ok handled in ShapeBase::renderObject)

We could go on to enable cloaking, but thats a tad more complicated :)
#4
10/11/2005 (3:53 pm)
I have been noticing quite a few problems with this code as-is.

Firstly, the code kept generating odd shaders. I eventually figured out that for some really wierd reason, the feature structure (that sets which features a generated shader uses) was being mysteriously corrupted. I ended up moving the visibility feature up one to before the fog feature :

In struct GFXShaderFeatureData:
...
   Visibility,
   Fog,
   NumFeatures,
   };
(Also changed the order of execution in FeatureMgr::init() to maintain consistency).

And also, in Material::setShaderConstants, i removed the (float*) bit on the visibility line:
GFX->setPixelShaderConstF( PC_VISIBILITY, &visibility, 1 );



Secondly, it didn't seem to work on cards such as the fabulous Radeon 9200. Granted, it could have been related to the above problem, but in the meanwhile i have added this check to MatInstance::determineFeatures:
if ( GFX->getPixelShaderVersion() >= 2.0 )
   {
      if ( i == GFXShaderFeatureData::Visibility )
      ...
   }
#5
03/29/2007 (7:49 am)
Anyone delve into updating this to current TGEA 1.0 technology? The rendering part has changed quite a bit in the last year and a half and it's still missing from the engine.
#6
05/22/2007 (3:29 am)
Won't it work as it is in TGEA 1.0?
#7
06/07/2007 (7:23 pm)
As I remember it, much of this seemed applicable in TGEA 1.0 but there were key changes in the way objects were rendered (more batch oriented now I think) and the appropriate adaptation did not seem obvious to me at the time. I'll revisit this problem shortly and maybe I'll work it out this time around.
#8
10/05/2007 (7:04 am)
I am in need of Fade, has anyone ported this to tgea 1.0+?

--J
#9
11/01/2007 (7:28 pm)
Bah.... sucks this isn't in Stock TGEA. I'll be shipping a similar feature in the ForestKit.
#10
11/02/2007 (3:16 pm)
ForestKit yay!
#11
11/02/2007 (3:22 pm)
@ Tom -- isn't the fact that sorted-meshes are broken also going to give you a problem, or does the ForestKit get around that?
#12
11/02/2007 (3:25 pm)
@Jeff - We don't ever sort meshes. Once you start sorting meshes performance goes down the crapper. Alpha test is your friend. ;)
#13
11/02/2007 (3:41 pm)
@ Tom - Hmmm... I guess I'll have think on that. I'm unaware of this particular alpha test usage.
#14
11/03/2007 (9:43 am)
Tom: does that solve the problems with trees with multiple alpha layers like a needle tree with multiple levels? Because by default TGEA sucks in that scenario and that badly. The alpha borders of the leafs totally kill the depth sorting and allow you to look through half the tree and the like. And splitting it up into XY single objects is kind of an overkill for a tree with a trunk and 3 levels of leaves (like a christmas tree)
#15
11/03/2007 (1:34 pm)
@Marc - Sure... it does solve that. In particular we use alpha test with blending disabled. We haven't experimented with alpha to coverage yet, but we sort of like the harder edge look really.
#16
11/03/2007 (2:29 pm)
That would be great :-)

And sounds like an interesting technique if it works and isn't too GPU consuming. TGEA already uses a fair amount of performance burning technics in stock ...
#17
03/26/2008 (12:33 pm)
No news on this topic? Does nobody have a working solution for 1.x?
#18
03/28/2008 (5:44 pm)
It seems a rather odd last name, I wonder if he is related to my idol Feargus Urquhart...