/// <summary>
        /// Create high resolution normal map
        /// </summary>
        /// <param name="heightmapSurface">High resolution height map</param>
        /// <param name="normalSurface">Render target surface for outputting the normal map</param>
        public void Execute(TerrainHeightmapSurface heightmapSurface, TerrainNormalSurface normalSurface, int nodeLevel)
        {
            normalSurface.Begin();
              normalSurface.Clear();

              // disable depth buffer and alpha blending
              device.DepthStencilState = DepthStencilState.None;
              device.BlendState = BlendState.Opaque;

              float normalScale = (float)Math.Pow(2.0, -(Constants.MaxTerrainNodeLevel - nodeLevel));
              normalScale *= 1000;

              generateNormalEffect.Parameters["NormalScale"].SetValue(normalScale);
              generateNormalEffect.Parameters["PatchWidth"].SetValue(heightmapSurface.Width);
              generateNormalEffect.Parameters["PatchHeight"].SetValue(heightmapSurface.Height);
              generateNormalEffect.Parameters["heightmap"].SetValue(heightmapSurface.Texture);

              for (int i = 0; i < generateNormalEffect.CurrentTechnique.Passes.Count; i++)
              {
            EffectPass pass = generateNormalEffect.CurrentTechnique.Passes[i];

            pass.Apply();
            device.DrawUserPrimitives(PrimitiveType.TriangleStrip, normalSurface.Vertices, 0, 2, vertexPositionTexture);
              }

              normalSurface.End();
        }
        public void Execute(TerrainHeightmapSurface surface, TerrainNodeBounds bounds)
        {
            surface.Begin();
              surface.Clear();

              //device.VertexDeclaration = vertexPositionTexture;

              // disable depth buffer and alpha blending
              device.DepthStencilState = DepthStencilState.None;
              device.BlendState = BlendState.Opaque;

              generateTerrainEffect.Parameters["PermutationMap"].SetValue(permutationTexture);
              generateTerrainEffect.Parameters["GradientMap"].SetValue(gradientTexture);
              generateTerrainEffect.Parameters["PatchLeft"].SetValue((float)bounds.Left);
              generateTerrainEffect.Parameters["PatchTop"].SetValue((float)bounds.Top);
              generateTerrainEffect.Parameters["PatchWidth"].SetValue((float)bounds.Width);
              generateTerrainEffect.Parameters["PatchHeight"].SetValue((float)bounds.Height);
              generateTerrainEffect.Parameters["FaceMatrix"].SetValue(CubeFaces.GetFace(bounds.Face).FaceMatrix);

              for (int i = 0; i < generateTerrainEffect.CurrentTechnique.Passes.Count; i++)
              {
            EffectPass pass = generateTerrainEffect.CurrentTechnique.Passes[i];
            pass.Apply();
            device.DrawUserPrimitives(PrimitiveType.TriangleStrip, surface.Vertices, 0, 2);
              }

              surface.End();
        }
    public void Execute(TerrainHeightmapSurface heightmapSurface, TerrainNormalSurface normalmapSurface, TerrainTextureSurface textureSurface, float HeightScale)
    {
      textureSurface.Begin();
      textureSurface.Clear();

      //device.VertexDeclaration = vertexPositionTexture;

      // disable depth buffer and alpha blending
      device.DepthStencilState = DepthStencilState.None;
      device.BlendState = BlendState.Opaque;

      generateTextureEffect.Parameters["HeightMapTexture"].SetValue(heightmapSurface.Texture);

#if !gradient
      generateTextureEffect.Parameters["HeightScale"].SetValue(HeightScale);
      generateTextureEffect.Parameters["NormalMapTexture"].SetValue(normalmapSurface.Texture);

      generateTextureEffect.Parameters["SlopeMapTexture"].SetValue(slopemapTexture);
      generateTextureEffect.Parameters["DiffuseTexture0"].SetValue(textures[0]);
      generateTextureEffect.Parameters["DiffuseTexture1"].SetValue(textures[1]);
      generateTextureEffect.Parameters["DiffuseTexture2"].SetValue(textures[2]);
      generateTextureEffect.Parameters["DiffuseTexture3"].SetValue(textures[3]);
      generateTextureEffect.Parameters["DiffuseTexture4"].SetValue(textures[4]);
      generateTextureEffect.Parameters["DiffuseTexture5"].SetValue(textures[5]);
      generateTextureEffect.Parameters["DiffuseTexture6"].SetValue(textures[6]);
      generateTextureEffect.Parameters["DiffuseTexture7"].SetValue(textures[7]);
      generateTextureEffect.Parameters["DiffuseTexture8"].SetValue(textures[8]);
      generateTextureEffect.Parameters["DiffuseTexture9"].SetValue(textures[9]);
      generateTextureEffect.Parameters["DiffuseTextureA"].SetValue(textures[10]);
      generateTextureEffect.Parameters["DiffuseTextureB"].SetValue(textures[11]);

#endif

      //Vector2 halfPixel = new Vector2(0.5f / heightmapSurface.Width, 0.5f / heightmapSurface.Height);
      //generateTextureEffect.Parameters["HalfPixel"].SetValue(halfPixel);

      for (int i = 0; i < generateTextureEffect.CurrentTechnique.Passes.Count; i++)
      {
        EffectPass pass = generateTextureEffect.CurrentTechnique.Passes[i];
        pass.Apply();
        device.DrawUserPrimitives(PrimitiveType.TriangleStrip, textureSurface.Vertices, 0, 2);
      }

      textureSurface.End();
    }