Engine Nine supports the heightmap based terrain through the Surface class. By giving a surface different materials, a surface will look like a terrain or an ocean.

To create a flat surface, set the Heightmap.Width, Heightmap.Height  and Heightmap.Step attached properties of the surface. The triangle mesh that represents the terrain will be subdivided based on the value of Heightmap.Width and Heightmap.Height. The Heightmap.Step property represents the size of the smallest subdivided area.


<Surface Heightmap.Width="128" Heightmap.Height="128" Heightmap.Step="1" Material="{BasicMaterial Texture={ContentReference Assets/box}}" />


To create a surface from heightmap, import a gray-scale texture to the content project, and then change the content processor to “Heightmap – Engine Nine”. The Height property of the processor represents the height of the highest point (or the whitest pixel in the grayscale texture). The Step property represents the horizontal size of each pixel. Some games uses raw bytes to represent heightmaps, Engine Nine supports both 8 bits and 16 bits raw file formats thought the “Raw Texture – Engine Nine” importer.

image image
<Surface Heightmap="{ContentReference Assets/Heightmap}" TextureTransform.Scale="0.2,0.2">
    <BasicMaterial LightingEnabled="True" Texture="{ContentReference Assets/box}" />

Notice how the TextureTransform.Scale property scales the mapped textures.


Terrain Level of Detail (LOD)

A surface is made up of surface patches. The yellow area in the following screenshot represents a surface patch. The size of each surface patch can be adjusted using Surface.PatchSegmentCount, but a surface patch has to be at least 2x2 in size, and the size of the heightmap has to be a multiple of patch segment count.

Engine Nine uses a technique called GeoMipMapping to implement the level of detail of terrain geometry. Each surface patch can have a different detail level based on the distance to the camera, patches further away from the camera will use a lower resolution model. Dynamic level of detail can be enabled using Surface.LevelOfDetailEnabled property, Surface.LevelOfDetailStart and Surface.LevelOfDetailEnd properties can be used to tweak how the detail level decreases.


<Surface Heightmap.Width="128" Heightmap.Height="128" Heightmap.Step="1" LevelOfDetailEnabled="True" LevelOfDetailEnd="5" PatchSegmentCount="8" />


Terrain Splatting

A terrain typically contains several layers and each layer uses a different material. A game might have a mud layer as the base layer, and adds additional grass and road layers on top of that. A popular way to render these layers is using terrain splatting. Each layer has a seamless texture and a grayscale alpha map. The alpha map represents the region of visible areas for that layer.

2 image 3 image


Engine Nine uses MaterialPaintGroup to represent the material of each layer. MaterialPaintGroup is itself a MaterialPart, but the magical part is that it can contain a list of other MaterialPart to represent materials for that particular layer. The following example shows a terrain material that contains 3 layers using MaterialPaintGroup. The first basic layer uses plain diffuse mapping. The second and third layer uses normal mapping. The MaterialPaintGroup.MaskTextures attached property specifies the alpha maps for this terrain material. The alpha maps of all the layers are compiled into the r, g, b, a channel of a single splat texture represented by the Splatter class. Again, splatter uses ExternalReference to refer the alpha map. VertexPositionNormalTangentBinormalTexture is used for VertexType because it is required for normal mapping.


<Surface Heightmap="{ContentReference ../Textures/RF1}"
            Transform.Position="-128, -20, -128" LevelOfDetailEnabled="False" 
            TextureTransform.Scale="0.2, 0.2" VertexType="VertexPositionNormalTangentBinormalTexture">
    <MaterialGroup MaterialPaintGroup.MaskTextureScale="5, 5">
                <ExternalReference />

            <DiffuseMaterialPart Texture="{ContentReference ../Textures/terrainTex}" />
            <DiffuseMaterialPart Texture="{ContentReference ../Textures/box}" />
            <SpecularMaterialPart SpecularColor="0.5, 0.5, 0.5" SpecularPower="64" />
            <NormalMapMaterialPart NormalMap="{ContentReference ../Textures/box_n}" />
            <NormalMapMaterialPart NormalMap="{ContentReference ../Textures/grass_n}" />
            <DiffuseMaterialPart Texture="{ContentReference ../Textures/grass}" />
            <SpecularMaterialPart SpecularColor="0.5, 0.5, 0.5" SpecularPower="64" />
        <DirectionalLightMaterialPart />

Last edited Sep 28, 2012 at 12:31 PM by yufeih, version 11


No comments yet.