Sign in to follow this  
Migi0027

Libnoise - C++ - Seamless generation

Recommended Posts

Hi guys,

 

recently I started with a simple terrain generation, and decided to visualize it in cubes, thought that's going to change. I chose libnoise, but after a while, I got some problems, like the terrain wasn't perfectly seamless.

 

zik20z.png

 

, so it seems like there is a wrong axis or something.

 

The world is generated in chunks, dynamically, here's how I do it:

 

Chunk Generation:

void GChunkClass::Generate(float x, float y, int size)
{
	posx = x;
	posy = y;

	// Create normal specular material
	m_tBump = new TextureObject();
	m_tBump->CreateTexture(m_pEngine->dev, "F:\\3d Art\\bump.jpg");

	m_mtBase = new MaterialClass();
	m_mtBase->Create(m_pEngine->dev, 
		std::string("Texture2D t_bump : register(t3);"),
		std::string(""),
		std::string("input.NormalSpec = t_bump.Sample(ss, input.texcoord).rgb;")
		);

	m_mMesh = new UMesh();

	// Push Cube
	m_pEngine->InstancedMesh.push_back(m_mMesh);

	// Create cube
	m_mMesh->InitCube(m_pEngine->devcon, m_pEngine->dev);

	m_mMesh->Translate(x, 0, y);

	float bX, bY;
	if (x == 0)
		bX = 0;
	else
		bX = x/20.0f;

	if (y == 0)
		bY = 0;
	else
		bY = y/20.0f;

	UPerlin perl;
	perl.SetOctaveCount(2);
	perl.SetFrequency(0.3f);

	// Generate random perlin map with NO color map
	PERLRETURN heightMap = PerlinMapGenerator::generateToFile(perl, size, size, 0.0f, 3.0f, bX, bY);

	UImg src(heightMap.heightFile);
	int width = src.width();
	int height = src.height();

	// Initialize stacksize
	m_mMesh->Instancing.reserve(src.size());

	_until(w, width)
	{
		_until(h, height)
		{
			m_mMesh->Instancing.push(Instance(w*2.0f, (float)(*src.data(w,h))/10.0f-10.0f, h*2.0f));
		}
	}

	// Create Buffer
	m_mMesh->Instancing.CreateBuffer(m_pEngine->dev);
	m_mMesh->Instanced = true;

	m_mMesh->SetMaterial(m_mtBase);
	m_mMesh->Parameters.SetTexture(m_tBump, 3);
}

How I generate the perlin map:

PERLRETURN PerlinMapGenerator::generateToFile(UPerlin module, 
											  int sizex, int sizey, 
											  float minHeight, float maxHeight, 
											  float boundX, float boundY, 
											  bool COLORMAP /* = false */, Group<Gradients>*GRADIENTS /* = nullptr */)
{
	double value = module.GetValue (14.50, 20.25, 75.75);
	utils::NoiseMap heightMap;
	utils::NoiseMapBuilderPlane heightMapBuilder;
	heightMapBuilder.SetSourceModule (module);
	heightMapBuilder.SetDestNoiseMap (heightMap);
	heightMapBuilder.SetDestSize (sizex, sizey);
	heightMapBuilder.SetBounds (boundX, boundX+5.0, boundY, boundY+5.0);
...

How the chunks are generated, externally (Beware my possible messy code!):

// Do we need new chunks?
	GChunkClass *currentChunk;
	int size = Chunks.size();
	until(size)
	{
		currentChunk = &Chunks[i];
		float x = currentChunk->getX();
		float y = currentChunk->getY();

		// Get Range
		if (sqrtf( //PS: cpos is the camera position
			((cPos->x - x) * (cPos->x - x))
			+
			((cPos->z - y) * (cPos->z - y))
			) > 200.0f)
		{
			// Too far away
			Chunks[i].setActive(false);
			continue;
		}
		else
			Chunks[i].setActive(true);

		// Do we need to generate a new chunk?
		// AXIS

		if (!foundChunk(x + 100, y + 100))
		{
			Chunks.push_back(GChunkClass(&engine));
			Chunks.back().Generate(x + 100, y + 100, 50);
		}

		if (!foundChunk(x - 100, y + 100))
		{
			Chunks.push_back(GChunkClass(&engine));
			Chunks.back().Generate(x - 100, y + 100, 50);
		}

		if (!foundChunk(x - 100, y - 100))
		{
			Chunks.push_back(GChunkClass(&engine));
			Chunks.back().Generate(x - 100, y - 100, 50);
		}

		if (!foundChunk(x + 100, y - 100))
		{
			Chunks.push_back(GChunkClass(&engine));
			Chunks.back().Generate(x + 100, y - 100, 50);
		}

		// AXIS

		if (!foundChunk(x, y + 100))
		{
			Chunks.push_back(GChunkClass(&engine));
			Chunks.back().Generate(x, y + 100, 50);
		}

		if (!foundChunk(x, y - 100))
		{
			Chunks.push_back(GChunkClass(&engine));
			Chunks.back().Generate(x, y - 100, 50);
		}

		if (!foundChunk(x + 100, y))
		{
			Chunks.push_back(GChunkClass(&engine));
			Chunks.back().Generate(x + 100, y, 50);
		}

		if (!foundChunk(x - 100, y))
		{
			Chunks.push_back(GChunkClass(&engine));
			Chunks.back().Generate(x - 100, y, 50);
		}
	}

So if you have time to spot the error, what on earth did I do wrong?

 

PS. Libnoise tutorial: http://libnoise.sourceforge.net/tutorials/tutorial2.html

 

Best Regards

{USERNAME}

Share this post


Link to post
Share on other sites

Are you sure that the libnoise bounds you set up for each chunk have a common edge?

 

For example :

int lowX = 100;
int lowY = 100;
int increment = 50;

for( int x = 0; x < someChunkWidth; x++ )
{
 hightMapBuilder.SetBounds( lowX, lowX + increment, lowY, lowY + increment );
 hightMapBuilder.Build()
 ...
 
 // do whatever you want with the data

 ...

 // Move the bounds of the noise generation
 lowX = lowX + increment;
}

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this