Sign in to follow this  

Libnoise - C++ - Seamless generation

This topic is 1630 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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

This topic is 1630 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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