Example #1
0
    // Initialize the terrain layers which define the detail textures which are painted onto
    // the terrain.
    // The materials are blended based on the terrain heights and slopes.
    private void InitializeTerrainLayers(ContentManager content)
    {
      var materialGravel = new TerrainMaterialLayer(_graphicsService)
      {
        DiffuseTexture = content.Load<Texture2D>("Terrain/Gravel-Diffuse"),
        NormalTexture = content.Load<Texture2D>("Terrain/Gravel-Normal"),
        SpecularTexture = content.Load<Texture2D>("Terrain/Gravel-Specular"),
        DiffuseColor = new Vector3F(1 / 0.246f, 1 / 0.205f, 1 / 0.171f) * new Vector3F(0.042f, 0.039f, 0.027f),
        TileSize = DetailCellSize * 512,
      };
      _terrainTile.Layers.Add(materialGravel);

      var materialGrass = new TerrainMaterialLayer(_graphicsService)
      {
        DiffuseTexture = content.Load<Texture2D>("Terrain/Grass-Dry-Diffuse"),
        NormalTexture = content.Load<Texture2D>("Terrain/Grass-Dry-Normal"),
        SpecularTexture = content.Load<Texture2D>("Terrain/Grass-Dry-Specular"),
        DiffuseColor = new Vector3F(0.17f, 0.20f, 0.11f),
        TileSize = DetailCellSize * 1024,
        TerrainHeightMin = -1000,
        TerrainHeightMax = 40,
        TerrainSlopeMin = -1,
        TerrainSlopeMax = 0.3f,
      };
      _terrainTile.Layers.Add(materialGrass);

      var materialGrassDry = new TerrainMaterialLayer(_graphicsService)
      {
        DiffuseTexture = content.Load<Texture2D>("Terrain/Grass-Dry-Diffuse"),
        NormalTexture = content.Load<Texture2D>("Terrain/Grass-Dry-Normal"),
        SpecularTexture = content.Load<Texture2D>("Terrain/Grass-Dry-Specular"),
        DiffuseColor = new Vector3F(0.15f, 0.18f, 0.12f),
        TileSize = DetailCellSize * 1024,
        TerrainHeightMin = -1000,
        TerrainHeightMax = 60,
        TerrainHeightBlendRange = 10,
        TerrainSlopeMin = 0.3f,
        TerrainSlopeMax = 0.4f,
      };
      _terrainTile.Layers.Add(materialGrassDry);

      var materialRock = new TerrainMaterialLayer(_graphicsService)
      {
        DiffuseTexture = content.Load<Texture2D>("Terrain/Rock-02-Diffuse"),
        NormalTexture = content.Load<Texture2D>("Terrain/Rock-02-Normal"),
        SpecularTexture = content.Load<Texture2D>("Terrain/Rock-02-Specular"),
        HeightTexture = content.Load<Texture2D>("Terrain/Rock-02-Height"),
        TileSize = DetailCellSize * 1024 * 10,
        DiffuseColor = new Vector3F(0.15f, 0.15f, 0.12f),
        SpecularColor = new Vector3F(2),
        SpecularPower = 100,
        TerrainHeightMin = -1000,
        TerrainHeightMax = 1000,
        TerrainHeightBlendRange = 20,
        TerrainSlopeMin = 0.5f,
        TerrainSlopeMax = 3,
      };
      _terrainTile.Layers.Add(materialRock);
      var materialRockDetail = new TerrainMaterialLayer(_graphicsService)
      {
        DiffuseTexture = content.Load<Texture2D>("Terrain/Rock-02-Diffuse"),
        NormalTexture = content.Load<Texture2D>("Terrain/Rock-02-Normal"),
        SpecularTexture = content.Load<Texture2D>("Terrain/Rock-02-Specular"),
        HeightTexture = content.Load<Texture2D>("Terrain/Rock-02-Height"),
        TileSize = DetailCellSize * 1024,
        DiffuseColor = new Vector3F(0.15f, 0.15f, 0.13f),
        SpecularColor = new Vector3F(0.5f),
        SpecularPower = 20,
        Alpha = 0.7f,
        FadeOutStart = 4,
        FadeOutEnd = 6,
        TerrainHeightMin = -1000,
        TerrainHeightMax = 1000,
        TerrainHeightBlendRange = 10,
        TerrainSlopeMin = 0.5f,
        TerrainSlopeMax = 3,
        BlendHeightInfluence = 1,
      };
      _terrainTile.Layers.Add(materialRockDetail);

      var materialSnow = new TerrainMaterialLayer(_graphicsService)
      {
        DiffuseTexture = content.Load<Texture2D>("Terrain/Snow-Diffuse"),
        NormalTexture = content.Load<Texture2D>("Terrain/Snow-Normal"),
        SpecularTexture = content.Load<Texture2D>("Terrain/Snow-Specular"),
        TileSize = DetailCellSize * 512,
        DiffuseColor = new Vector3F(1),
        SpecularColor = new Vector3F(1),
        SpecularPower = 100,
        TerrainHeightMin = 60,
        TerrainHeightMax = 1000,
        TerrainHeightBlendRange = 1,
        TerrainSlopeMin = -1,
        TerrainSlopeMax = 0.5f,
        TerrainSlopeBlendRange = 0.1f,
      };
      _terrainTile.Layers.Add(materialSnow);
    }
Example #2
0
    // Initialize the terrain layers which define the detail textures which are painted onto
    // the terrain.
    private void InitializeTerrainLayers(ContentManager content)
    {
      // The appearance of each terrain tile can be specified using layers. Each layer usually
      // specifies one material type, e.g. grass, rock, snow. Layers can also be used to add
      // decals or roads to the terrain, which is demonstrated in other samples.

      for (int row = 0; row < 2; row++)
      {
        for (int column = 0; column < 2; column++)
        {
          var terrainTile = _tiles[row, column].TerrainTile;
          string tilePostfix = "-" + row + "-" + column; // e.g. "-0-1"

          // This first layer contains only a base tint texture which is visible where no other
          // detail material layers are rendered (e.g. in the distance).
          var tintTexture = content.Load<Texture2D>("Terrain/Terrain001-Tint" + tilePostfix);
          var baseColorLayer = new TerrainMaterialLayer(_graphicsService)
          {
            TintTexture = tintTexture,
            TintStrength = 1,
          };
          terrainTile.Layers.Add(baseColorLayer);

          // The tiling of the detail textures can be visible and unattractive in the distance.
          // To avoid this, we can fade-out the detail material layers.
          int fadeOutStart = 4;   // The fade-out starts in clipmap level 4.
          int fadeOutEnd = 6;     // The fade-out ends in clipmap level 6, which means the layer is
                                  // not drawn into the detail clipmap levels >= 6.

          // Add a gravel texture which covers the whole terrain near the camera and fades
          // out in the distance.
          var materialGravel = new TerrainMaterialLayer(_graphicsService)
          {
            // The tiling detail material textures.
            DiffuseTexture = content.Load<Texture2D>("Terrain/Gravel-Diffuse"),
            NormalTexture = content.Load<Texture2D>("Terrain/Gravel-Normal"),
            SpecularTexture = content.Load<Texture2D>("Terrain/Gravel-Specular"),

            // The size of one tile in world space units.
            TileSize = DetailCellSize * 512,

            // The diffuse detail texture is multiplied with the tint texture.
            TintTexture = tintTexture,
            TintStrength = 1.0f,

            // The diffuse color is set to 1 / average texture color. This turns the average
            // detail texture color and conserve the color of the tint texture.
            // (To determine the average color manually: Load the texture in a image-processing
            // tool, like GIMP. Blur the texture until it is one solid color. Pick the color using
            // a color picker tool. If the image-processing tool uses sRGB, then convert the color
            // to linear RGB: colorLinear = colorSRgb^2.2)
            DiffuseColor = new Vector3F(1 / 0.246f, 1 / 0.205f, 1 / 0.171f),

            SpecularColor = new Vector3F(0.5f),
            SpecularPower = 20,

            FadeOutStart = fadeOutStart,
            FadeOutEnd = fadeOutEnd,
          };
          terrainTile.Layers.Add(materialGravel);

          // Over the gravel we add a layer of grass.
          // A blend texture contains a mask which defines where the grass is visible.
          // The blend range determines how quickly the width of the transition between grass
          // and the underlying layers.
          float blendRange = 0.6f;
          var materialGrass = new TerrainMaterialLayer(_graphicsService)
          {
            DiffuseTexture = content.Load<Texture2D>("Terrain/Grass-Dry-Diffuse"),
            NormalTexture = content.Load<Texture2D>("Terrain/Grass-Dry-Normal"),
            SpecularTexture = content.Load<Texture2D>("Terrain/Grass-Dry-Specular"),
            TileSize = DetailCellSize * 1024,
            TintTexture = tintTexture,
            TintStrength = 1,
            DiffuseColor = new Vector3F(1 / 0.25f),
            SpecularColor = new Vector3F(1),
            SpecularPower = 20,

            BlendTexture = content.Load<Texture2D>("Terrain/Terrain001-Blend-Grass" + tilePostfix),
            // The blend texture can contain a blend mask in each channel (R, G, B or A).
            // Use the red channel (channel 0)
            BlendTextureChannel = 0,
            BlendRange = blendRange,

            FadeOutStart = fadeOutStart,
            FadeOutEnd = fadeOutEnd,
          };
          terrainTile.Layers.Add(materialGrass);

          // Side note: Terrain layers can also be defined using .drmat files:
          //terrainTile.Layers.Add(new TerrainMaterialLayer(content.Load<Material>("Terrain/MyLayerMaterial")));

          // Let's add a layer of sand. Sand occurs only in the tiles 1/0 and 1/1.
          if (row == 1)
          {
            var materialSand = new TerrainMaterialLayer(_graphicsService)
            {
              DiffuseTexture = content.Load<Texture2D>("Terrain/Sand-Diffuse"),
              NormalTexture = content.Load<Texture2D>("Terrain/Sand-Normal"),
              SpecularTexture = content.Load<Texture2D>("Terrain/Sand-Specular"),
              TileSize = DetailCellSize * 512,
              TintTexture = tintTexture,
              TintStrength = 1f,
              DiffuseColor = new Vector3F(1 / 0.429f, 1 / 0.347f, 1 / 0.275f),
              SpecularColor = new Vector3F(10),
              SpecularPower = 50,
              BlendTexture = content.Load<Texture2D>("Terrain/Terrain001-Blend-Sand" + tilePostfix),
              BlendTextureChannel = 0,
              BlendRange = blendRange,
              FadeOutStart = fadeOutStart,
              FadeOutEnd = fadeOutEnd,
            };
            terrainTile.Layers.Add(materialSand);
          }

          // The dirt layer is used on the brown rocks near the beach. To make the rocks more
          // interesting we use a rock texture with a larger tile size. This is also visible
          // in the distance.
          // Then we also mix-in the gravel texture to add more detail near the camera.
          var materialDirt = new TerrainMaterialLayer(_graphicsService)
          {
            DiffuseTexture = content.Load<Texture2D>("Terrain/Rock-02-Diffuse"),
            NormalTexture = content.Load<Texture2D>("Terrain/Rock-02-Normal"),
            SpecularTexture = content.Load<Texture2D>("Terrain/Rock-02-Specular"),
            HeightTexture = content.Load<Texture2D>("Terrain/Rock-02-Height"),
            TileSize = DetailCellSize * 1024 * 10,
            TintTexture = tintTexture,
            TintStrength = 1f,
            DiffuseColor = new Vector3F(1 / 0.702f) * new Vector3F(0.9f, 1, 0.9f),
            SpecularColor = new Vector3F(2),
            SpecularPower = 100,
            BlendTexture = content.Load<Texture2D>("Terrain/Terrain001-Blend-Dirt" + tilePostfix),
            BlendTextureChannel = 0,
            BlendRange = blendRange,
          };
          terrainTile.Layers.Add(materialDirt);
          var materialDirtDetail = new TerrainMaterialLayer(_graphicsService)
          {
            DiffuseTexture = content.Load<Texture2D>("Terrain/Gravel-Diffuse"),
            NormalTexture = content.Load<Texture2D>("Terrain/Gravel-Normal"),
            SpecularTexture = content.Load<Texture2D>("Terrain/Gravel-Specular"),
            TileSize = DetailCellSize * 512,
            TintTexture = tintTexture,
            TintStrength = 1f,
            DiffuseColor = new Vector3F(1 / 0.59f, 1 / 0.537f, 1 / 0.5f),
            SpecularColor = new Vector3F(0.5f),
            SpecularPower = 20,

            // This layer is transparent to blend with the underlying rock texture.
            Alpha = 0.5f,

            BlendTexture = content.Load<Texture2D>("Terrain/Terrain001-Blend-Dirt" + tilePostfix),
            BlendTextureChannel = 0,
            BlendRange = blendRange,
            FadeOutStart = fadeOutStart,
            FadeOutEnd = fadeOutEnd,
          };
          terrainTile.Layers.Add(materialDirtDetail);

          // The gray rocks use two layered rock textures.
          var materialRock = new TerrainMaterialLayer(_graphicsService)
          {
            DiffuseTexture = content.Load<Texture2D>("Terrain/Rock-02-Diffuse"),
            NormalTexture = content.Load<Texture2D>("Terrain/Rock-02-Normal"),
            SpecularTexture = content.Load<Texture2D>("Terrain/Rock-02-Specular"),
            HeightTexture = content.Load<Texture2D>("Terrain/Rock-02-Height"),
            TileSize = DetailCellSize * 1024 * 20,
            TintTexture = tintTexture,
            TintStrength = 1f,
            DiffuseColor = new Vector3F(1 / 0.702f) * 1,
            SpecularColor = new Vector3F(2),
            SpecularPower = 100,
            BlendTexture = content.Load<Texture2D>("Terrain/Terrain001-Blend-Rock" + tilePostfix),
            BlendTextureChannel = 0,
            BlendRange = blendRange,
          };
          terrainTile.Layers.Add(materialRock);
          var materialRockDetail = new TerrainMaterialLayer(_graphicsService)
          {
            DiffuseTexture = content.Load<Texture2D>("Terrain/Rock-02-Diffuse"),
            NormalTexture = content.Load<Texture2D>("Terrain/Rock-02-Normal"),
            SpecularTexture = content.Load<Texture2D>("Terrain/Rock-02-Specular"),
            HeightTexture = content.Load<Texture2D>("Terrain/Rock-02-Height"),
            TileSize = DetailCellSize * 1024,
            TintTexture = tintTexture,
            TintStrength = 1f,
            DiffuseColor = new Vector3F(1 / 0.702f) * 1,
            SpecularColor = new Vector3F(2),
            SpecularPower = 100,
            Alpha = 0.5f,
            BlendTexture = content.Load<Texture2D>("Terrain/Terrain001-Blend-Rock" + tilePostfix),
            BlendTextureChannel = 0,
            BlendRange = blendRange,
            FadeOutStart = fadeOutStart,
            FadeOutEnd = fadeOutEnd,
          };
          terrainTile.Layers.Add(materialRockDetail);

          // Add some gravel from hydraulic erosion over the rocks.
          var materialFlow = new TerrainMaterialLayer(_graphicsService)
          {
            DiffuseTexture = content.Load<Texture2D>("Terrain/Gravel-Diffuse"),
            NormalTexture = content.Load<Texture2D>("Terrain/Gravel-Normal"),
            SpecularTexture = content.Load<Texture2D>("Terrain/Gravel-Specular"),
            TileSize = DetailCellSize * 512,
            TintTexture = tintTexture,
            TintStrength = 1f,
            DiffuseColor = new Vector3F(1 / 0.246f, 1 / 0.205f, 1 / 0.171f),
            SpecularColor = new Vector3F(1),
            BlendRange = blendRange,
            BlendTexture = content.Load<Texture2D>("Terrain/Terrain001-Blend-Flow" + tilePostfix),
            BlendTextureChannel = 0,
            SpecularPower = 20,
            FadeOutStart = fadeOutStart,
            FadeOutEnd = fadeOutEnd,
          };
          terrainTile.Layers.Add(materialFlow);

          // Add snow in the tiles 0/0 and 0/1.
          if (row == 0)
          {
            var materialSnow = new TerrainMaterialLayer(_graphicsService)
            {
              DiffuseTexture = content.Load<Texture2D>("Terrain/Snow-Diffuse"),
              NormalTexture = content.Load<Texture2D>("Terrain/Snow-Normal"),
              SpecularTexture = content.Load<Texture2D>("Terrain/Snow-Specular"),
              TileSize = DetailCellSize * 512,
              TintTexture = tintTexture,
              TintStrength = 0.0f,
              DiffuseColor = new Vector3F(1),
              SpecularColor = new Vector3F(10),
              SpecularPower = 100,
              BlendTexture = content.Load<Texture2D>("Terrain/Terrain001-Blend-Snow" + tilePostfix),
              BlendTextureChannel = 0,
              BlendRange = 0.5f,
              BlendThreshold = 0.4f,
              BlendNoiseInfluence = 0.5f,
              NoiseTileSize = 20,
            };
            terrainTile.Layers.Add(materialSnow);
          }
        }
      }
    }
Example #3
0
    public ParallaxTerrainSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;

      _graphicsScreen = new DeferredGraphicsScreen(Services);
      _graphicsScreen.DrawReticle = true;
      GraphicsService.Screens.Insert(0, _graphicsScreen);
      GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

      Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);

      var scene = _graphicsScreen.Scene;
      Services.Register(typeof(IScene), null, scene);

      // Add standard game objects.
      var cameraGameObject = new CameraObject(Services, 5000);
      cameraGameObject.ResetPose(new Vector3F(0, 2, 0), 0, 0);
      GameObjectService.Objects.Add(cameraGameObject);
      _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

      Simulation.ForceEffects.Add(new Gravity());
      Simulation.ForceEffects.Add(new Damping());
      GameObjectService.Objects.Add(new GrabObject(Services));
      GameObjectService.Objects.Add(new DynamicSkyObject(Services, true, false, true)
      {
        EnableCloudShadows = false,
      });
      GameObjectService.Objects.Add(new ObjectCreatorObject(Services));

      // Create terrain.
      _terrainObject = new TerrainObject(Services);
      GameObjectService.Objects.Add(_terrainObject);

      // To see parallax occlusion mapping, we need a detail texture with a height map.
      // In this sample we reuse the pavement texture of the ParallaxMappingSample and 
      // add it to the terrain.
      for (int row = 0; row < 2; row++)
      {
        for (int column = 0; column < 2; column++)
        {
          var terrainTile = _terrainObject.TerrainNode.Terrain.Tiles[row * 2 + column];
          string tilePostfix = "-" + row + "-" + column; // e.g. "-0-1"

          var materialPavement = new TerrainMaterialLayer(GraphicsService)
          {
            DiffuseColor = new Vector3F(1),
            SpecularColor = new Vector3F(5),
            SpecularPower = 20,
            DiffuseTexture = ContentManager.Load<Texture2D>("Parallax/AgedPavement_diffuse"),
            NormalTexture = ContentManager.Load<Texture2D>("Parallax/AgedPavement_normal"),
            SpecularTexture = ContentManager.Load<Texture2D>("Parallax/AgedPavement_specular"),
            HeightTexture = ContentManager.Load<Texture2D>("Parallax/AgedPavement_height"),
            TileSize = 0.005f * 512,
            BlendTexture = ContentManager.Load<Texture2D>("Terrain/Terrain001-Blend-Grass" + tilePostfix),
            BlendTextureChannel = 0,
            BlendHeightInfluence = 0.5f,
            BlendThreshold = 0.5f,
            BlendRange = 0.5f,
          };

          terrainTile.Layers.Add(materialPavement);
        }
      }

      // Replace the terrain effects with effects which support parallax occlusion mapping.
      UpdateTerrainMaterial(true);

      CreateGuiControls();
    }
Example #4
0
    public TerrainTextureSample(Microsoft.Xna.Framework.Game game)
      : base(game)
    {
      SampleFramework.IsMouseVisible = false;

      _graphicsScreen = new DeferredGraphicsScreen(Services);
      _graphicsScreen.DrawReticle = true;
      GraphicsService.Screens.Insert(0, _graphicsScreen);
      GameObjectService.Objects.Add(new DeferredGraphicsOptionsObject(Services));

      Services.Register(typeof(DebugRenderer), null, _graphicsScreen.DebugRenderer);

      var scene = _graphicsScreen.Scene;
      Services.Register(typeof(IScene), null, scene);

      // Add gravity and damping to the physics simulation.
      Simulation.ForceEffects.Add(new Gravity());
      Simulation.ForceEffects.Add(new Damping());

      // Add a custom game object which controls the camera.
      var cameraGameObject = new CameraObject(Services, 60);
      cameraGameObject.ResetPose(new Vector3F(0, 1.8f, 0), 0, 0);
      GameObjectService.Objects.Add(cameraGameObject);
      _graphicsScreen.ActiveCameraNode = cameraGameObject.CameraNode;

      for (int i = 0; i < 10; i++)
        GameObjectService.Objects.Add(new DynamicObject(Services, 1));

      GameObjectService.Objects.Add(new DynamicSkyObject(Services, true, false, true));

      // Create a simple flat terrain.
      var terrain = new Terrain();
      _terrainTile = new TerrainTile(GraphicsService)
      {
        OriginX = -100,
        OriginZ = -100,
        CellSize = 1,
      };
      terrain.Tiles.Add(_terrainTile);

      // Create a flat dummy height texture.
      float[] heights = new float[200 * 200];
      Texture2D heightTexture = null;
      TerrainHelper.CreateHeightTexture(
        GraphicsService.GraphicsDevice,
        heights,
        200,
        200,
        false,
        ref heightTexture);
      _terrainTile.HeightTexture = heightTexture;
      
      var shadowMapEffect = ContentManager.Load<Effect>("DigitalRune/Terrain/TerrainShadowMap");
      var gBufferEffect = ContentManager.Load<Effect>("DigitalRune/Terrain/TerrainGBuffer");
      var materialEffect = ContentManager.Load<Effect>("DigitalRune/Terrain/TerrainMaterial");
      var material = new Material
      {
        { "ShadowMap", new EffectBinding(GraphicsService, shadowMapEffect, null, EffectParameterHint.Material) },
        { "GBuffer", new EffectBinding(GraphicsService, gBufferEffect, null, EffectParameterHint.Material) },
        { "Material", new EffectBinding(GraphicsService, materialEffect, null, EffectParameterHint.Material) }
      };
      var terrainNode = new TerrainNode(terrain, material)
      {
        DetailClipmap =
        {
          CellsPerLevel = 1364,
          NumberOfLevels = 9,
          EnableMipMap = true,
        },
      };
      scene.Children.Add(terrainNode);

      // Add 3 detail textures layers: gravel, rock, snow.
      float detailCellSize = terrainNode.DetailClipmap.CellSizes[0];
      var materialGravel = new TerrainMaterialLayer(GraphicsService)
      {
        DiffuseTexture = ContentManager.Load<Texture2D>("Terrain/Gravel-Diffuse"),
        NormalTexture = ContentManager.Load<Texture2D>("Terrain/Gravel-Normal"),
        SpecularTexture = ContentManager.Load<Texture2D>("Terrain/Gravel-Specular"),
        TileSize = detailCellSize * 512,
        BlendRange = 0.1f,
      };
      _terrainTile.Layers.Add(materialGravel);

      var noiseTexture = NoiseHelper.GetNoiseTexture(GraphicsService, 128, 60);

      var materialRock = new TerrainMaterialLayer(GraphicsService)
      {
        DiffuseTexture = ContentManager.Load<Texture2D>("Terrain/Rock-02-Diffuse"),
        NormalTexture = ContentManager.Load<Texture2D>("Terrain/Rock-02-Normal"),
        SpecularTexture = ContentManager.Load<Texture2D>("Terrain/Rock-02-Specular"),
        HeightTexture = ContentManager.Load<Texture2D>("Terrain/Rock-02-Height"),
        TileSize = detailCellSize * 1024,
        DiffuseColor = new Vector3F(1 / 0.702f),
        BlendTexture = noiseTexture,
        BlendTextureChannel = 0,
        BlendRange = 0.1f,
        TerrainHeightBlendRange = 0.1f,
      };
      _terrainTile.Layers.Add(materialRock);

      var materialSnow = new TerrainMaterialLayer(GraphicsService)
      {
        DiffuseTexture = ContentManager.Load<Texture2D>("Terrain/Snow-Diffuse"),
        NormalTexture = ContentManager.Load<Texture2D>("Terrain/Snow-Normal"),
        SpecularTexture = ContentManager.Load<Texture2D>("Terrain/Snow-Specular"),
        TileSize = detailCellSize * 512,
        BlendTexture = noiseTexture,
        BlendTextureChannel = 1,
        BlendRange = 0.1f,
      };
      _terrainTile.Layers.Add(materialSnow);

      // Create a flat plane for collision detection.
      var rigidBody = new RigidBody(new PlaneShape(), new MassFrame(), null)
      {
        MotionType = MotionType.Static,
      };
      Simulation.RigidBodies.Add(rigidBody);

      CreateGuiControls();
    }