Browse Source

terrain_blending_opengl_port_from_lukas_code

Anis A. Hireche 10 years ago
parent
commit
a954daa43f
28 changed files with 248 additions and 240 deletions
  1. 223 47
      Engine/source/terrain/glsl/terrFeatureGLSL.cpp
  2. 9 0
      Engine/source/terrain/terrCellMaterial.cpp
  3. 4 0
      Engine/source/terrain/terrCellMaterial.h
  4. 5 1
      Engine/source/terrain/terrMaterial.cpp
  5. 7 0
      Engine/source/terrain/terrMaterial.h
  6. BIN
      Templates/Empty/game/art/terrains/Example/dirt_grass_n.png
  7. BIN
      Templates/Empty/game/art/terrains/Example/grass1_dry.jpg
  8. BIN
      Templates/Empty/game/art/terrains/Example/grass1_dry_d.png
  9. BIN
      Templates/Empty/game/art/terrains/Example/grass1_dry_n.png
  10. BIN
      Templates/Empty/game/art/terrains/Example/grass1_n.png
  11. BIN
      Templates/Empty/game/art/terrains/Example/grass2_n.png
  12. BIN
      Templates/Empty/game/art/terrains/Example/road_n.png
  13. BIN
      Templates/Empty/game/art/terrains/Example/rocks1_n.png
  14. BIN
      Templates/Empty/game/art/terrains/Example/rocktest_n.png
  15. BIN
      Templates/Empty/game/art/terrains/Example/sand_n.png
  16. BIN
      Templates/Empty/game/art/terrains/Example/snowtop_n.png
  17. BIN
      Templates/Empty/game/art/terrains/Example/stone_n.png
  18. BIN
      Templates/Full/game/art/terrains/Example/dirt_grass_n.png
  19. BIN
      Templates/Full/game/art/terrains/Example/grass1_dry_n.png
  20. BIN
      Templates/Full/game/art/terrains/Example/grass1_n.png
  21. BIN
      Templates/Full/game/art/terrains/Example/grass2_n.png
  22. BIN
      Templates/Full/game/art/terrains/Example/road_n.png
  23. BIN
      Templates/Full/game/art/terrains/Example/rocks1_n.png
  24. BIN
      Templates/Full/game/art/terrains/Example/rocktest_n.png
  25. BIN
      Templates/Full/game/art/terrains/Example/sand_n.png
  26. BIN
      Templates/Full/game/art/terrains/Example/snowtop_n.png
  27. BIN
      Templates/Full/game/art/terrains/Example/stone_n.png
  28. 0 192
      Templates/Full/game/art/terrains/materials.cs

+ 223 - 47
Engine/source/terrain/glsl/terrFeatureGLSL.cpp

@@ -379,6 +379,9 @@ void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
    const U32 detailIndex = getProcessIndex();
    Var *inTex = getVertTexCoord( "texCoord" );
 
+   // new terrain
+   bool hasNormal = fd.features.hasFeature(MFT_TerrainNormalMap, detailIndex);
+
    MultiLine *meta = new MultiLine;
 
    // We need the negative tangent space view vector
@@ -447,6 +450,95 @@ void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
    meta->addStatement( new GenOp( "   @ = calcBlend( @.x, @.xy, @, @ );\r\n", 
                                     new DecOp( detailBlend ), detailInfo, inTex, layerSize, layerSample ) );
 
+   // New terrain
+
+   Var *lerpBlend = (Var*)LangElement::find("lerpBlend");
+   if (!lerpBlend)
+   {
+	   lerpBlend = new Var;
+	   lerpBlend->setType("float");
+	   lerpBlend->setName("lerpBlend");
+	   lerpBlend->uniform = true;
+	   lerpBlend->constSortPos = cspPrimitive;
+   }
+
+
+   Var *blendDepth = (Var*)LangElement::find(String::ToString("blendDepth%d", detailIndex));
+   if (!blendDepth)
+   {
+	   blendDepth = new Var;
+	   blendDepth->setType("float");
+	   blendDepth->setName(String::ToString("blendDepth%d", detailIndex));
+	   blendDepth->uniform = true;
+	   blendDepth->constSortPos = cspPrimitive;
+   }
+
+   Var *baseColor = (Var*)LangElement::find("baseColor");
+   Var *outColor = (Var*)LangElement::find(getOutputTargetVarName(OutputTarget::DefaultTarget));
+
+   if (!outColor)
+   {
+	   // create color var
+	   outColor = new Var;
+	   outColor->setType("float4");
+	   outColor->setName("col");
+	   meta->addStatement(new GenOp("   @;\r\n", new DecOp(outColor)));
+	   //outColor->setStructName("OUT");
+   }
+
+   Var *detailColor = (Var*)LangElement::find("detailColor");
+   if (!detailColor)
+   {
+	   detailColor = new Var;
+	   detailColor->setType("float4");
+	   detailColor->setName("detailColor");
+	   meta->addStatement(new GenOp("   @;\r\n", new DecOp(detailColor)));
+   }
+
+   // Get the detail texture.
+   Var *detailMap = new Var;
+   detailMap->setType("sampler2D");
+   detailMap->setName(String::ToString("detailMap%d", detailIndex));
+   detailMap->uniform = true;
+   detailMap->sampler = true;
+   detailMap->constNum = Var::getTexUnitNum();     // used as texture unit num here
+
+   // Get the normal map texture.
+   Var *normalMap = _getNormalMapTex();
+
+   // Issue happens somewhere here -----
+
+   // Sample the normal map.
+   //
+   // We take two normal samples and lerp between them for
+   // side projection layers... else a single sample.
+   LangElement *texOp;
+
+   // Note that we're doing the standard greyscale detail 
+   // map technique here which can darken and lighten the 
+   // diffuse texture.
+   //
+   // We take two color samples and lerp between them for
+   // side projection layers... else a single sample.
+   //
+   if (fd.features.hasFeature(MFT_TerrainSideProject, detailIndex))
+   {
+	   meta->addStatement(new GenOp("   @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n",
+		   detailColor, detailMap, inDet, detailMap, inDet, inTex));
+
+	   texOp = new GenOp("lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z )",
+		   normalMap, inDet, normalMap, inDet, inTex);
+   }
+   else
+   {
+	   meta->addStatement(new GenOp("   @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n",
+		   detailColor, detailMap, inDet));
+
+	   texOp = new GenOp("tex2D(@, @.xy)", normalMap, inDet);
+   }
+
+   // New terrain
+
    // Get a var and accumulate the blend amount.
    Var *blendTotal = (Var*)LangElement::find( "blendTotal" );
    if ( !blendTotal )
@@ -460,6 +552,95 @@ void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
    // Add to the blend total.
    meta->addStatement( new GenOp( "   @ = max( @, @ );\r\n", blendTotal, blendTotal, detailBlend ) );
 
+   // New terrain
+   Var *bumpNorm = (Var*)LangElement::find("bumpNormal");
+   Var *invBlend = (Var*)LangElement::find("invBlend");
+   Var *currentAlpha = (Var*)LangElement::find("currentAlpha");
+   Var *ma = (Var*)LangElement::find("ma");
+   Var *b1 = (Var*)LangElement::find("b1");
+   Var *b2 = (Var*)LangElement::find("b2");
+
+   // Get a var and accumulate the blend amount.
+   if (!currentAlpha)
+   {
+	   currentAlpha = new Var;
+	   currentAlpha->setName("currentAlpha");
+	   currentAlpha->setType("float");
+	   meta->addStatement(new GenOp("   @ = 0;\r\n", new DecOp(currentAlpha)));
+   }
+
+   if (hasNormal)
+   {
+	   // create bump normal
+	   bool bumpNormWasDefined = bumpNorm ? true : false;
+	   LangElement *bumpNormDecl = bumpNorm;
+
+	   if (!bumpNormWasDefined)
+	   {
+		   bumpNorm = new Var;
+		   bumpNorm->setName("bumpNormal");
+		   bumpNorm->setType("float4");
+		   bumpNormDecl = new DecOp(bumpNorm);
+	   }
+	   meta->addStatement(new GenOp("   @ = @;\r\n", bumpNormDecl, texOp));
+	   meta->addStatement(new GenOp("   @.a = max(@.a, 0.000001);\r\n", bumpNorm, bumpNorm));
+
+	   // -----
+
+	   // Get a var and accumulate the blend amount.
+	   if (!invBlend)
+	   {
+		   invBlend = new Var;
+		   invBlend->setName("invBlend");
+		   invBlend->setType("float");
+		   meta->addStatement(new GenOp("   @;\r\n", new DecOp(invBlend)));
+	   }
+
+	   // Get a var and accumulate the blend amount.
+	   if (!ma)
+	   {
+		   ma = new Var;
+		   ma->setName("ma");
+		   ma->setType("float");
+		   meta->addStatement(new GenOp("   @;\r\n", new DecOp(ma)));
+	   }
+
+	   // Get a var and accumulate the blend amount.
+	   if (!b1)
+	   {
+		   b1 = new Var;
+		   b1->setName("b1");
+		   b1->setType("float");
+		   meta->addStatement(new GenOp("   @;\r\n", new DecOp(b1)));
+	   }
+	   // Get a var and accumulate the blend amount.
+	   if (!b2)
+	   {
+		   b2 = new Var;
+		   b2->setName("b2");
+		   b2->setType("float");
+		   meta->addStatement(new GenOp("   @;\r\n", new DecOp(b2)));
+	   }
+
+	   meta->addStatement(new GenOp("   if( @ <= 0 ) \r\n   { \r\n", lerpBlend));
+
+	   meta->addStatement(new GenOp("      @ = 1-@;\r\n", invBlend, detailBlend));
+
+	   meta->addStatement(new GenOp("      @ = max(@.a + @, @ + @) - @;\r\n", ma, bumpNorm, detailBlend, currentAlpha, invBlend, blendDepth));
+
+	   meta->addStatement(new GenOp("      @ = max(@.a + @ - @, 0);\r\n", b1, bumpNorm, detailBlend, ma));
+
+	   meta->addStatement(new GenOp("      @ = max(@ + @ - @, 0);\r\n", b2, currentAlpha, invBlend, ma));
+
+	   meta->addStatement(new GenOp("   }\r\n"));
+   }
+   else
+   {
+	   meta->addStatement(new GenOp("   @ = max(@,@);\r\n", currentAlpha, currentAlpha, detailBlend));
+   }
+
+   // New terrain
+
    // If we had a parallax feature... then factor in the parallax
    // amount so that it fades out with the layer blending.
    if ( fd.features.hasFeature( MFT_TerrainParallaxMap, detailIndex ) )
@@ -495,58 +676,36 @@ void TerrainDetailMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
       return;
    }
 
-   Var *detailColor = (Var*)LangElement::find( "detailColor" ); 
-   if ( !detailColor )
-   {
-      detailColor = new Var;
-      detailColor->setType( "vec4" );
-      detailColor->setName( "detailColor" );
-      meta->addStatement( new GenOp( "   @;\r\n", new DecOp( detailColor ) ) );
-   }
-
-   // Get the detail texture.
-   Var *detailMap = new Var;
-   detailMap->setType( "sampler2D" );
-   detailMap->setName( String::ToString( "detailMap%d", detailIndex ) );
-   detailMap->uniform = true;
-   detailMap->sampler = true;
-   detailMap->constNum = Var::getTexUnitNum();     // used as texture unit num here
+   // used as texture unit num here
 
    // If we're using SM 3.0 then take advantage of 
    // dynamic branching to skip layers per-pixel.
-   
 
    if ( GFX->getPixelShaderVersion() >= 3.0f )
       meta->addStatement( new GenOp( "   if ( @ > 0.0f )\r\n", detailBlend ) );
 
    meta->addStatement( new GenOp( "   {\r\n" ) );
 
-   // Note that we're doing the standard greyscale detail 
-   // map technique here which can darken and lighten the 
-   // diffuse texture.
-   //
-   // We take two color samples and lerp between them for
-   // side projection layers... else a single sample.
-   //
-   if ( fd.features.hasFeature( MFT_TerrainSideProject, detailIndex ) )
-   {
-      meta->addStatement( new GenOp( "      @ = ( lerp( tex2D( @, @.yz ), tex2D( @, @.xz ), @.z ) * 2.0 ) - 1.0;\r\n", 
-                                                detailColor, detailMap, inDet, detailMap, inDet, inTex ) );
-   }
-   else
-   {
-      meta->addStatement( new GenOp( "      @ = ( tex2D( @, @.xy ) * 2.0 ) - 1.0;\r\n", 
-                                       detailColor, detailMap, inDet ) );
-   }
 
    meta->addStatement( new GenOp( "      @ *= @.y * @.w;\r\n",
                                     detailColor, detailInfo, inDet ) );
 
-   Var *baseColor = (Var*)LangElement::find( "baseColor" );
-   Var *outColor = (Var*)LangElement::find( "col" );
+   // New terrain
+   if (hasNormal)
+   {
+	   meta->addStatement(new GenOp("      if( @ <= 0 ) \r\n", lerpBlend));
+	   meta->addStatement(new GenOp("         @.rgb = ((@ + @).rgb * @ + @.rgb * @) / (@ + @);\r\n", outColor, baseColor, detailColor, b1, outColor, b2, b1, b2));
+	   meta->addStatement(new GenOp("      else\r\n"));
+   }
 
-   meta->addStatement( new GenOp( "      @ = lerp( @, @ + @, @ );\r\n",
-                                    outColor, outColor, baseColor, detailColor, detailBlend ) );
+   meta->addStatement(new GenOp("      @ += @ * @;\r\n", outColor, detailColor, detailBlend));
+
+   // New terrain
+   if (hasNormal)
+   {
+	   meta->addStatement(new GenOp("      if( @ <= 0 ) \r\n", lerpBlend));
+	   meta->addStatement(new GenOp("         @ = (@.a * @ + @ * @) / (@ + @);\r\n", currentAlpha, bumpNorm, b1, currentAlpha, b2, b1, b2));
+   }
 
    meta->addStatement( new GenOp( "   }\r\n" ) );
 
@@ -812,13 +971,9 @@ void TerrainMacroMapFeatGLSL::processPix(   Vector<ShaderComponent*> &componentL
    meta->addStatement( new GenOp( "      @ *= @.y * @.w;\r\n",
                                     detailColor, detailInfo, inDet ) );
 
-   Var *baseColor = (Var*)LangElement::find( "baseColor" );
    Var *outColor = (Var*)LangElement::find( "col" );
 
-   meta->addStatement( new GenOp( "      @ = lerp( @, @ + @, @ );\r\n",
-                                    outColor, outColor, outColor, detailColor, detailBlend ) );
-   //outColor, outColor, baseColor, detailColor, detailBlend ) );
-
+   meta->addStatement(new GenOp("      @ += @ * @;\r\n", outColor, detailColor, detailBlend));
    meta->addStatement( new GenOp( "   }\r\n" ) );
 
    output = meta;
@@ -920,15 +1075,36 @@ void TerrainNormalMapFeatGLSL::processPix(   Vector<ShaderComponent*> &component
       texOp = new GenOp( "tex2D(@, @.xy)", normalMap, inDet );
 
    // create bump normal
-   Var *bumpNorm = new Var;
-   bumpNorm->setName( "bumpNormal" );
-   bumpNorm->setType( "vec4" );
+   // New terrain
+   Var *bumpNorm = (Var*)LangElement::find("bumpNormal");
+   bool bumpNormWasDefined = bumpNorm ? true : false;
+   LangElement *bumpNormDecl = bumpNorm;
+
+   if (!bumpNormWasDefined)
+   {
+	   bumpNorm = new Var;
+	   bumpNorm->setName("bumpNormal");
+	   bumpNorm->setType("float4");
+	   bumpNormDecl = new DecOp(bumpNorm);
+   }
 
-   LangElement *bumpNormDecl = new DecOp( bumpNorm );
    meta->addStatement( expandNormalMap( texOp, bumpNormDecl, bumpNorm, fd ) );
 
+   // New terrain
+   Var *lerpBlend = (Var*)LangElement::find("lerpBlend");
+   AssertFatal(lerpBlend, "The lerpBlend is missing!");
+   Var *b1 = (Var*)LangElement::find("b1");
+   AssertFatal(b1, "The b1 is missing!");
+   Var *b2 = (Var*)LangElement::find("b2");
+   AssertFatal(b2, "The b2 is missing!");
+
    // Normalize is done later... 
    // Note: The reverse mul order is intentional. Affine matrix.
+
+   // New terrain
+   meta->addStatement(new GenOp("      if( @ <= 0 ) \r\n", lerpBlend));
+   meta->addStatement(new GenOp("         @ = (tMul( @.xyz, @ ).rgb * @ + @.rgb * @) / (@ + @);\r\n", gbNormal, bumpNorm, viewToTangent, b1, gbNormal, b2, b1, b2));
+   meta->addStatement(new GenOp("      else\r\n"));
    meta->addStatement( new GenOp( "      @ = lerp( @, tMul( @.xyz, @ ), min( @, @.w ) );\r\n", 
       gbNormal, gbNormal, bumpNorm, viewToTangent, detailBlend, inDet ) );
 

+ 9 - 0
Engine/source/terrain/terrCellMaterial.cpp

@@ -563,6 +563,10 @@ bool TerrainCellMaterial::_createPass( Vector<MaterialInfo*> *materials,
       matInfo->detailInfoVConst = pass->shader->getShaderConstHandle( avar( "$detailScaleAndFade%d", i ) );
       matInfo->detailInfoPConst = pass->shader->getShaderConstHandle( avar( "$detailIdStrengthParallax%d", i ) );
 
+	  // New blending
+	  matInfo->lerpBlend = pass->shader->getShaderConstHandle("$lerpBlend");
+	  matInfo->blendDepth = pass->shader->getShaderConstHandle(avar("$blendDepth%d", i));
+
       matInfo->detailTexConst = pass->shader->getShaderConstHandle( avar( "$detailMap%d", i ) );
       if ( matInfo->detailTexConst->isValid() )
       {
@@ -700,6 +704,11 @@ void TerrainCellMaterial::_updateMaterialConsts( Pass *pass )
       pass->consts->setSafe( matInfo->detailInfoVConst, detailScaleAndFade );
       pass->consts->setSafe( matInfo->detailInfoPConst, detailIdStrengthParallax );
 
+	  // New blending
+	  bool lerpBlend = Con::getBoolVariable("$Pref::Terrain::LerpBlend", true);
+	  pass->consts->setSafe(matInfo->lerpBlend, lerpBlend ? 1.0f : 0.0f);
+	  pass->consts->setSafe(matInfo->blendDepth, matInfo->mat->getBlendDepth());
+
 	// macro texture info
 
       F32 macroSize = matInfo->mat->getMacroSize();

+ 4 - 0
Engine/source/terrain/terrCellMaterial.h

@@ -80,6 +80,10 @@ protected:
       GFXShaderConstHandle *detailInfoVConst;
       GFXShaderConstHandle *detailInfoPConst;
 
+	  // New blending
+	  GFXShaderConstHandle *lerpBlend;
+	  GFXShaderConstHandle *blendDepth;
+
 	  GFXShaderConstHandle *macroInfoVConst;
       GFXShaderConstHandle *macroInfoPConst;
    };

+ 5 - 1
Engine/source/terrain/terrMaterial.cpp

@@ -65,7 +65,8 @@ TerrainMaterial::TerrainMaterial()
       mMacroSize( 200.0f ),
       mMacroStrength( 0.7f ),
       mMacroDistance( 500.0f ),
-      mParallaxScale( 0.0f )
+	  mParallaxScale(0.0f),
+	  mBlendDepth(0.4f)
 {
 }
 
@@ -97,6 +98,9 @@ void TerrainMaterial::initPersistFields()
    addField( "parallaxScale", TypeF32, Offset( mParallaxScale, TerrainMaterial ), "Used to scale the height from the normal map to give some self "
 	   "occlusion effect (aka parallax) to the terrain material" );
 
+   addField("blendDepth", TypeF32, Offset(mBlendDepth, TerrainMaterial), "Depth for blending the textures using the new blending method by Lukas Joergensen."
+	   "Higher numbers = larger blend radius.");
+
    Parent::initPersistFields();
 
    // Gotta call this at least once or it won't get created!

+ 7 - 0
Engine/source/terrain/terrMaterial.h

@@ -74,6 +74,11 @@ protected:
    ///
    F32 mParallaxScale;
 
+   /// Depth for blending the textures using the new
+   /// blending method. Higher numbers = larger blend
+   /// radius.
+   F32 mBlendDepth;
+
 public:
 
    TerrainMaterial();
@@ -119,6 +124,8 @@ public:
 
    F32 getParallaxScale() const { return mParallaxScale; }
 
+   F32 getBlendDepth() const { return mBlendDepth; }
+
 };
 
 #endif // _TERRMATERIAL_H_

BIN
Templates/Empty/game/art/terrains/Example/dirt_grass_n.png


BIN
Templates/Empty/game/art/terrains/Example/grass1_dry.jpg


BIN
Templates/Empty/game/art/terrains/Example/grass1_dry_d.png


BIN
Templates/Empty/game/art/terrains/Example/grass1_dry_n.png


BIN
Templates/Empty/game/art/terrains/Example/grass1_n.png


BIN
Templates/Empty/game/art/terrains/Example/grass2_n.png


BIN
Templates/Empty/game/art/terrains/Example/road_n.png


BIN
Templates/Empty/game/art/terrains/Example/rocks1_n.png


BIN
Templates/Empty/game/art/terrains/Example/rocktest_n.png


BIN
Templates/Empty/game/art/terrains/Example/sand_n.png


BIN
Templates/Empty/game/art/terrains/Example/snowtop_n.png


BIN
Templates/Empty/game/art/terrains/Example/stone_n.png


BIN
Templates/Full/game/art/terrains/Example/dirt_grass_n.png


BIN
Templates/Full/game/art/terrains/Example/grass1_dry_n.png


BIN
Templates/Full/game/art/terrains/Example/grass1_n.png


BIN
Templates/Full/game/art/terrains/Example/grass2_n.png


BIN
Templates/Full/game/art/terrains/Example/road_n.png


BIN
Templates/Full/game/art/terrains/Example/rocks1_n.png


BIN
Templates/Full/game/art/terrains/Example/rocktest_n.png


BIN
Templates/Full/game/art/terrains/Example/sand_n.png


BIN
Templates/Full/game/art/terrains/Example/snowtop_n.png


BIN
Templates/Full/game/art/terrains/Example/stone_n.png


+ 0 - 192
Templates/Full/game/art/terrains/materials.cs

@@ -20,195 +20,3 @@
 // IN THE SOFTWARE.
 //-----------------------------------------------------------------------------
 
-// ----------------------------------------------------------------------------
-// Sample grass
-// ----------------------------------------------------------------------------
-
-singleton Material(TerrainFX_grass1)
-{
-   mapTo = "grass1";
-   footstepSoundId = 0;
-   terrainMaterials = "1";
-   ShowDust = "1";
-   showFootprints = "1";
-   materialTag0 = "Terrain";
-   effectColor[0] = "0.42 0.42 0 1";
-   effectColor[1] = "0.42 0.42 0 1";
-   impactSoundId = "0";
-};
-
-new TerrainMaterial()
-{
-   internalName = "grass1";
-   diffuseMap = "art/terrains/Example/grass1";
-   detailMap = "art/terrains/Example/grass1_d";
-   detailSize = "10";
-   isManaged = "1";
-   detailBrightness = "1";
-   Enabled = "1";
-   diffuseSize = "200";
-};
-
-singleton Material(TerrainFX_grass2)
-{
-   mapTo = "grass2";
-   footstepSoundId = 0;
-   terrainMaterials = "1";
-   ShowDust = "1";
-   showFootprints = "1";
-   materialTag0 = "Terrain";
-   effectColor[0] = "0.42 0.42 0 1";
-   effectColor[1] = "0.42 0.42 0 1";
-   impactSoundId = "0";
-};
-
-new TerrainMaterial()
-{
-   internalName = "grass2";
-   diffuseMap = "art/terrains/Example/grass2";
-   detailMap = "art/terrains/Example/grass2_d";
-   detailSize = "10";
-   isManaged = "1";
-   detailBrightness = "1";
-   Enabled = "1";
-   diffuseSize = "200";
-};
-
-singleton Material(TerrainFX_grass1dry)
-{
-   mapTo = "grass1_dry";
-   footstepSoundId = 0;
-   terrainMaterials = "1";
-   ShowDust = "1";
-   showFootprints = "1";
-   materialTag0 = "Terrain";
-   effectColor[0] = "0.63 0.55 0 1";
-};
-
-new TerrainMaterial()
-{
-   internalName = "grass1_dry";
-   diffuseMap = "art/terrains/Example/grass1_dry";
-   detailMap = "art/terrains/Example/grass1_dry_d";
-   detailSize = "10";
-   detailDistance = "100";
-   isManaged = "1";
-   detailBrightness = "1";
-   Enabled = "1";
-   diffuseSize = "250";
-   detailStrength = "2";
-};
-
-singleton Material(TerrainFX_dirt_grass)
-{
-   mapTo = "dirt_grass";
-   footstepSoundId = 0;
-   terrainMaterials = "1";
-   ShowDust = "1";
-   showFootprints = "1";
-   materialTag0 = "Terrain";
-   effectColor[0] = "0.63 0.55 0 1";
-};
-
-new TerrainMaterial()
-{
-   internalName = "dirt_grass";
-   diffuseMap = "art/terrains/Example/dirt_grass";
-   detailMap = "art/terrains/Example/dirt_grass_d";
-   detailSize = "5";
-   detailDistance = "100";
-   isManaged = "1";
-   detailBrightness = "1";
-   Enabled = "1";
-   diffuseSize = "200";
-};
-
-// ----------------------------------------------------------------------------
-// Sample rock
-// ----------------------------------------------------------------------------
-
-singleton Material(TerrainFX_rocktest)
-{
-   mapTo = "rocktest";
-   footstepSoundId = "1";
-   terrainMaterials = "1";
-   ShowDust = "1";
-   showFootprints = "1";
-   materialTag0 = "Terrain";
-   impactSoundId = "1";
-   effectColor[0] = "0.25 0.25 0.25 1";
-   effectColor[1] = "0.25 0.25 0.25 0";
-};
-
-new TerrainMaterial()
-{
-   internalName = "rocktest";
-   diffuseMap = "art/terrains/Example/rocktest";
-   detailMap = "art/terrains/Example/rocktest_d";
-   detailSize = "10";
-   detailDistance = "100";
-   isManaged = "1";
-   detailBrightness = "1";
-   Enabled = "1";
-   diffuseSize = "400";
-};
-
-// ----------------------------------------------------------------------------
-// Sample rock
-// ----------------------------------------------------------------------------
-
-singleton Material(TerrainFX_stone)
-{
-   mapTo = "stone";
-   footstepSoundId = "1";
-   terrainMaterials = "1";
-   ShowDust = "1";
-   showFootprints = "1";
-   materialTag0 = "Terrain";
-   impactSoundId = "1";
-   effectColor[0] = "0.25 0.25 0.25 1";
-   effectColor[1] = "0.25 0.25 0.25 0";
-};
-
-new TerrainMaterial()
-{
-   internalName = "stone";
-   diffuseMap = "art/terrains/Example/stone";
-   detailMap = "art/terrains/Example/stone_d";
-   detailSize = "10";
-   detailDistance = "100";
-   isManaged = "1";
-   detailBrightness = "1";
-   Enabled = "1";
-   diffuseSize = "400";
-   useSideProjection = "0";
-};
-// ----------------------------------------------------------------------------
-// Sample sand
-// ----------------------------------------------------------------------------
-
-singleton Material(TerrainFX_sand)
-{
-   mapTo = "sand";
-   footstepSoundId = "3";
-   terrainMaterials = "1";
-   ShowDust = "1";
-   showFootprints = "1";
-   materialTag0 = "Terrain";
-   specularPower[0] = "1";
-   effectColor[0] = "0.84 0.71 0.5 1";
-   effectColor[1] = "0.84 0.71 0.5 0.349";
-};
-
-new TerrainMaterial()
-{
-   internalName = "sand";
-   diffuseMap = "art/terrains/Example/sand";
-   detailMap = "art/terrains/Example/sand_d";
-   detailSize = "10";
-   detailDistance = "100";
-   isManaged = "1";
-   detailBrightness = "1";
-   Enabled = "1";
-   diffuseSize = "200";
-};