Terrain Smoothing
Theory
Take one point. Then take its 9 neighbouring points. Work
out the average height of the 9 points, and set it to the original point. Pass
it through multiple times to be smoothed more.
Example
The framework already has a function for height generation
and a function for random noise generation. It also has a single dimensional
array to represent the 2D terrain so the example is in a triple nested for loop.
In an ideal world a multidimensional array would better suit the representation
of a 2D plane.
- The smoothing was put into its own function and called from within the terrain generation function. Strength will be how many times you want to pass the terrain through to smooth it. The higher the number the more it will be smoothed.
bool TerrainClass::GenerateSmoothing(float strength)
{
- Then make a for loop to carry out the smoothing as many times as required.
for(int times; times < strength; times++)
{
- Start cycling through the terrain array.
for(int j = 0; j < m_terrainHeight; j++)
{
- In this example it has to go through 2 loops because it's a single dimensional array.
for(int i = 0; i < m_terrainWidth; i++)
{
- Make a temporary variable to hold the value of the average height for the 9 adjacent heights.
float totalAdjacentHeight = 0;
- Find each point using the array (see diagram) and add it to the temporary variable.
i+1, j+1
|
i+1, j
|
i+1, j-1
|
i, j + 1
|
i, j
|
i, j-1
|
i-1, j+1
|
i-1, j
|
i-1, j-1
|
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j - 1), i - 1].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j ), i -
1].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j + 1), i - 1].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j - 1), i ].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j ), i ].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j + 1), i ].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j - 1), i + 1].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j ), i +
1].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j + 1), i + 1].y;
7.
Retrieve the original
point(the centre position in the diagram) and set it equal to the temporary
variable (after you've / 9 (9 for 9 neighbours) this is the average)
m_heightMap[(m_terrainHeight * j),
i].y = (float)(totalAdjacentHeight
/ 9.0);
8.
Close off the
function.
}
}
}
return true;
}
Source Code
bool TerrainClass::GenerateSmoothing(float strength)
{
for(int times; times < strength; times++)
{
for(int j = 0; j < m_terrainHeight; j++)
{
for(int i = 0; i < m_terrainWidth; i++)
{
float totalAdjacentHeight = 0;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j - 1), i - 1].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j ), i -
1].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j + 1), i - 1].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j - 1), i ].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j ), i ].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j + 1), i ].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j - 1), i + 1].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j ), i +
1].y;
totalAdjacentHeight += m_heightMap[(m_terrainHeight
* j + 1), i + 1].y;
m_heightMap[(m_terrainHeight * j),
i].y = (float)(totalAdjacentHeight
/ 9.0);
}
}
}
return true;
}
No comments:
Post a Comment