Game Development Community

parallax mapping broken?

by Andy Schatz · in Torque 3D Professional · 06/24/2009 (5:35 pm) · 17 replies

I believe parallax mapping may be broken. First, if I set the parallax scale > 0 on any terrain texture, it gets applied to all of them. Second, it appears to stop rendering the detail texture in part of the map.

www.pocketwatchgames.com/content-img/gg/screenshot_005-00000.png

#1
06/24/2009 (5:47 pm)
Quote:On paralax it seems like its not working right when its only a single layer with the parallax feature. Looks like a bug that needs to be fixed.
It still does this when I apply parallax to all of my terrain textures.
#2
06/25/2009 (7:43 am)
Hi all,

with a standard installation of Beta3 and a new project as Testlevel i got the same results.
The Paralaxmapping seem to be only on one quart of the map.
System: NVidia280 with Vista64Bit

cu
Oliver
#3
06/25/2009 (9:36 am)
Hum... i'm having trouble interpreting that screenshot Andy.

Could you (or Qbound) post another with and without parallax so i can see the difference. A screenshot closer to the surface... ideally where it shows half working and the other half not... would be ideal.
#4
06/25/2009 (10:05 am)
OK, I found part of the problem. Since when you set the parallax scale for one, it sets them for all, if you have any textures without normal maps it does the weird black areas and the rendering on only one quarter of the map. However, I also see inconsistent results even when all terrain textures have normals. See below screenshots:

The green texture doesn't have a normal in this shot, though the parallax scale is only set > 0 on the grey rock texture you see in the background.
www.pocketwatchgames.com/content-img/gg/screenshot_006-00000.png

Parallax scale is set to 0 on the grey texture
www.pocketwatchgames.com/content-img/gg/screenshot_006-00001.png

No parallax
www.pocketwatchgames.com/content-img/gg/screenshot_006-00002.png

Parallax (no normal on the green texture)
www.pocketwatchgames.com/content-img/gg/screenshot_006-00003.png

Parallax (with all normals set, parallax scale set to 0.1, detail textures stop rendering)
www.pocketwatchgames.com/content-img/gg/screenshot_006-00004.png
#5
06/25/2009 (11:17 am)
Thanks Andy that shows the issues off much better.

I got some debugging to do here... as i find fixes i'll post back code changes for everyone.

#6
06/25/2009 (12:45 pm)
BTW we've got some funny looking artifacting on the first shot in the above post because we've got spec in our alpha channel on that green texture. Waiting and hoping for spec :)
#7
06/29/2009 (11:42 am)
Logging this as THREED-534
#8
07/26/2009 (5:33 pm)
Do i loose bonus points for talking a month to get to this issue? :)

Ok... the fix...

First in terrain/hlsl/terrFeatureHLSL.cpp in the function TerrainDetailMapFeatHLSL::processPix() around line 324:

// Calculate the blend for this detail texture.
   meta->addStatement( new GenOp( "   @ = calcBlend( @.x, @.xy, @, @ );\r\n", 
                                    new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );

   // BEGIN ADDED CODE!
   Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
   if ( !blendTotal )
   {
      blendTotal = new Var;
      blendTotal->setName( "blendTotal" );
      blendTotal->setType( "float" );
      meta->addStatement( new GenOp( "   @ = 0;\r\n", new DecOp( blendTotal ) ) );
   }

   // Add to the blend total.
   meta->addStatement( new GenOp( "   @ += @;\r\n", blendTotal, detailBlend ) );
   // END ADDED CODE

   // Nothing more to do for a detail texture in prepass.
   if ( fd.features.hasFeature( MFT_PrePassConditioner ) )
   {
      output = meta;
      return;
   }

Then further down in TerrainNormalMapFeatHLSL::processPix() around line 450:

MultiLine *meta = new MultiLine;

   Var *worldToTangent = getInWorldToTangent( componentList );

   // REMOVE THIS!
   // Get a var to accumulate the blend amount.
   //Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
   //if ( !blendTotal )
   //{
   //   blendTotal = new Var;
   //   blendTotal->setName( "blendTotal" );
   //   blendTotal->setType( "float" );
   //   meta->addStatement( new GenOp( "   @ = 0;\r\n", new DecOp( blendTotal ) ) );
   //}

   // This var is read from GBufferConditionerHLSL and 
   // used in the prepass output.
   Var *gbNormal = (Var*)LangElement::find( "gbNormal" );
   if ( !gbNormal )
   {

... and alittle further below in the same function remove this...

meta->addStatement( new GenOp( "   {\r\n" ) );

   // REMOVE THIS TOO!
   // Add to the blend total.
   //meta->addStatement( new GenOp( "      @ += @;\r\n", blendTotal, detailBlend ) ); 

   // Get the normal map texture.
   Var *normalMap = _getNormalMapTex();

Finally in terrain/terrCellMaterial.cpp in the function TerrainCellMaterial::_createPass() around line 219:

// The prepass needs a special additive feature which
      // overides the depth normally put into the alpha channel
      // of the output color.
      if ( !firstPass ) // CHANGED!
         features.addFeature( MFT_TerrainAdditive );

This should fix most of the issues in this thread i believe. SVN r22697.
#9
07/26/2009 (6:22 pm)
@Tom
And the bad news is my terrain has completely vanished.
TerrainCellMaterial::init - Failed to create pass!
//It prints this error 290 times in the console

GPU=7900GS

Just doing a recheck to make sure I didn't screw anything up.
#10
07/26/2009 (6:25 pm)
@Steve - Probably a typo in your merge. In TerrainCellMaterial::_createPass() change this line to enable logging...
GFXShader::setLogging( true, true );
Then you'll get an error message we can diagnose.


#11
07/26/2009 (7:01 pm)
edit:
needlessly long list removed from thread
#12
07/26/2009 (7:58 pm)
AH!

Found it... see the "rn" in here...

meta->addStatement( new GenOp( "   @ = 0;\r\n", new DecOp( blendTotal ) ) );

... stupid website ate the rn and left rn in the code listing.

EDIT: I fixed it in the post above. It seems like when you edit a post it removes the slashes. Weird. Give the change another try Steve.
#13
07/26/2009 (8:20 pm)
Okay, I have the terrain back, though it hasn't affected either of these two issues.
#14
07/31/2009 (12:51 am)
After implementing this fix, I started experiencing issues with certain terrain materials not being fogged (actually, the same materials that didn't render detail textures prior to the fix). The heavier the fog, the more noticeable the issue. I was able to fix the issue for myself with the following fix, which made sense to me:

I implemented the following change in terrain/terrCellMaterial.cpp in the function TerrainCellMaterial::_createPass() around line 219:

// The prepass needs a special additive feature which   
// overides the depth normally put into the alpha channel   
// of the output color.   
if ( !firstPass && !isLastPass ) // CHANGED!   
   features.addFeature( MFT_TerrainAdditive );

// If this is the last pass then add fog if we need it.
if (  isLastPass &&
      !gClientSceneGraph->usePostEffectFog() )
   features.addFeature( MFT_Fog );

This change made sense because prior to Tom's fix, the TerrainAdditive shader feature wasn't being applied at the same time as the Fog feature. With this fix the TerrainAdditive shader feature no longer gets applied in the last pass when the Fog gets applied.
#15
07/31/2009 (9:02 pm)
@Stephane - This is in Basic Lighting correct?

I think your fix may be correct only in BL mode... not sure yet. I need to take a closer look. :)

#16
07/31/2009 (10:24 pm)
@Tom - Yes, this was in Basic Lighting... sorry, can't really test in Advanced Lighting...
#17
08/14/2009 (1:56 am)
An update to the fix I mentioned earlier. That actually isn't a valid fix since not adding the MFT_TerrainAdditive feature causes certain terrain detail textures to not get rendered...

To fix the issue's I was seeing, I actually ended up removing the 'isLastPass' variable entirely (and obviously also removing it from any 'if' statements being used with it). I can't seem to understand what that variable is being used for... It seems like it's being used to remove the MFT_TerrainLightMap and MFT_Fog features when trying to create a shader with a reduced number of materials. Is that correct?

I guess what was happening is my card couldn't support X number of terrain materials in one shader so it halved the number of materials and removed the TerrainLightMap and MFT_Fog features... I don't know...