Erosion 3

From DaveWiki

Jump to: navigation, search

In this example we will use our basic erosion algorithm developed last time to perform more extensive erosion on our height map. Instead of eroding from a single point we will start an erosion cycle from every point in the height map.

From the previous example's code we'll change how we set the color/height during our erosion path by overriding the CErosionSample2::ErodePoint() method. For each point along the path we're eroding we are simply reducing the height of the map slightly. Then we add the ErodeAll() method to begin an erosion cycle at each point in the map.

#include "erosion2.h"
 
/*
 * Fills in a height map with a constant value.
 */
void FillHeightMap (utils::NoiseMap& HeightMap, const float Value)
{
	int X, Y;
 
	for (Y = 0; Y < HeightMap.GetHeight(); ++Y)
	{
		for (X = 0; X < HeightMap.GetWidth(); ++X)
		{
			HeightMap.SetValue(X, Y, Value);
		}
	}
}
 
class CErosionSample3 : public CErosionSample2
{
public:
 
	float		EROSION_DELTA;
 
	utils::NoiseMap	m_ErosionMap;
 
	/*
	 * Class Constructor
	 */
	CErosionSample3()
	{
		EROSION_DELTA = 0.0005f;
	}
 
	/*
	 * Override to initialize the new erosion height map.
	 */
	virtual void CreateBaseNoise (void)
	{
		CErosionSample2::CreateBaseNoise();
 
		m_ErosionMap.SetSize(m_Width, m_Height);
		davelib::FillHeightMap(m_ErosionMap, 0);
	}
 
	/*
	 * Override to provide a gentler erosion pattern.
	 */
	virtual void ErodePoint (const int X, const int Y)
	{
		m_HeightMap.SetValue(X, Y, m_HeightMap.GetValue(X, Y) - EROSION_DELTA);
		m_ErosionMap.SetValue(X, Y, m_ErosionMap.GetValue(X, Y) - EROSION_DELTA);
	}
 
	/*
	 * Starts one erosion cycle from every point in the height map.
	 */
	virtual void ErodeAll (void)
	{
		utils::NoiseMap OrigMap;
		int X, Y;
		davelib::CProfileTime Profile(_T("ErodeAll()"));
 
		OrigMap = m_HeightMap;
		OrigMap.SetBorderValue(2);
 
		for (Y = 0; Y < OrigMap.GetHeight(); ++Y)
		{
			printf("Eroding row %d of %d...\n", Y, OrigMap.GetHeight());
 
			for (X = 0; X < OrigMap.GetWidth(); ++X)
			{
				Erode(OrigMap, X, Y);
			}
		}
 
	}
 
};
 
int _tmain(int argc, _TCHAR* argv[])
{
	CErosionSample3 ErosionSample;
 
	ErosionSample.CreateBaseNoise();
	ErosionSample.ErodeAll();
 
	davelib::OutputHeightMapGrayScale("erosion3a.bmp", ErosionSample.m_HeightMap);
	davelib::OutputHeightMapGrayScale("erosion3b.bmp", ErosionSample.m_ErosionMap);
 
	return 0;
}

Using this code results in (complete height map to the left, eroded areas only highlighted on the right):
Image:Erosion3.jpg Image:Erosion3a.jpg
Note that for this example the erosion amount was purposefully made large to make it more visible. Although this process is very simple it is already creating some interesting looking features.

Personal tools