Page 1 of 2

Textures discolored at edges

Posted: Sun Jan 06, 2008 12:06 am
by pwierz
I wrote some code that takes a big (1025x1025) heightmap and splits it into 64 129x129 heightmaps and stiches them together. It also takes a large texture (2048x2048) and splits it into 64 256x256 textures. But at the edge of each heightmap the texture gets discolored and causes an obvious seam. Can anyone take a look at my code and see if you see anything? At first I thought it might be a normals thing but when I create it, I set all normals to straight up (plus the heightmap doesn't show the discoloration when I don't draw the texture).

Code: Select all

bool CTiledHeightmap::LoadTerrain(irr::video::IVideoDriver* &driver,scene::ISceneManager* &smgr,float track_scale){
	m_fTrackScale = track_scale;
	video::ITexture* detail = driver->getTexture("terrain/detail.bmp");

//Open up the big heighmap and big texture
	video::IImage* heightMap = smgr->getVideoDriver()->createImageFromFile("terrain/island/terrain/heightmap.bmp");
	video::IImage* bigTex = smgr->getVideoDriver()->createImageFromFile("terrain/island/terrain/tex.bmp");
	s32 data[129*129];

//Split it up into 8x8 tiles
	for(int tile=0;tile<64;tile++){

//Sub will be a 129x129 tile of the heightmap
		video::IImage* sub = driver->createImageFromData(video::ECF_A8R8G8B8,core::dimension2di(129,129),&data);
 
//Create a 256x256 texture and copy the appropriate portion of the big texture to it.
		video::ITexture *txt = driver->addTexture(core::dimension2d<s32>(256,256), "texture", video::ECF_A8R8G8B8); 
		video::SColor *p = (video::SColor*)txt->lock(); 

		for(u32 j=0; j<txt->getSize().Height; j++) 
		 for(u32 i=0; i<txt->getSize().Width; i++) 
			p[j * txt->getSize().Width + i] = bigTex->getPixel(256*(tile%8) + i,256*(tile/8)+j); 		 
		txt->unlock();
		
		txt->regenerateMipMapLevels();

//Now copy the correct portion of the large heightmap to the tile
		sub->lock();
		for(int i=0;i < 129;i++)
			for(int j=0; j < 129 ; j++)
				sub->setPixel(i,j,heightMap->getPixel(i + (128 * (tile %8)),j + (128 * (tile/8))));
		sub->unlock();

//I split the engine a little bit so you can make a terrainscenenode from an image
		node[tile] = smgr->addTerrainSceneNode(sub,0,-1,core::vector3df(0.0,0.0,0.0),core::vector3df(0.0,0.0,0.0),core::vector3df(1.0,1.0,1.0),video::SColor(255,255,255,255),5,scene::ETPS_17,5,false);

//Add the texture
		node[tile]->setMaterialFlag(video::EMF_LIGHTING, false);
		node[tile]->setMaterialTexture(0,txt);
		//node[tile]->setMaterialTexture(1,detail);
		node[tile]->setMaterialType(video::EMT_DETAIL_MAP);
		node[tile]->setScale(core::vector3df(track_scale,track_scale,track_scale));
		node[tile]->setPosition(core::vector3df(128.0f * (tile%8)*track_scale,0.0f,128.0f * (tile/8)*track_scale));
		node[tile]->scaleTexture(1.0,64.0);
	}
	
//This function takes the adjacent tiles and stitches the edges together.
//Theoretically this should be unnecessary but the smoothing algorithm can cause slight differences at the edges.
	for(int i=0; i<7;i++)
		for(int j=0; j<7; j++)
		{
			StitchHeightmap(node[i*8 + j],node[i*8 + j + 1],0);
			StitchHeightmap(node[i*8 + j],node[(i+1)*8 + j],1);
		}

	return true;
}
Here's what it looks like:

Image

Posted: Sun Jan 06, 2008 12:27 am
by Frosty Topaz
It looks like the texture isn't so much being discolored as fading out... like the alpha values are changing for some reason. The code as it stands looks fine to me.

Oh, it might be useful to try creating the terrain tiles without smoothing and then skipping the "StitchHeightmap()" calls. Just in case the problem is being caused there.

And if you're looking for a fix for the terrain smoothing edge thing you can check out my post here.

Posted: Sun Jan 06, 2008 12:31 am
by pwierz
I don't think it's fading out. It looks more blue than white (its untextured color). I'm thinking it may be a memory stomping problem but I can't see it anywhere.

Posted: Sun Jan 06, 2008 12:34 am
by Frosty Topaz
I didn't mean as in fading to white, but as in fading to whatever is behind it. I think I can see clouds as well as sky through that ground.

Posted: Sun Jan 06, 2008 12:38 am
by pwierz
Frosty Topaz wrote:I didn't mean as in fading to white, but as in fading to whatever is behind it. I think I can see clouds as well as sky through that ground.
I thought that too but it's probably not that. The sky is the CSkyDome (or whatever the class is) and it only extends 5 degrees below the horizon. But I appreciate the help.

Posted: Sun Jan 06, 2008 1:52 am
by Acki
hmm, this looks to me like a texture bug I discovered long time ago... :shock:
either it's this one:
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=13977
the problem there is that in normal case the texture coordinates must be from 0.0 to 1.0
but this is not with Irrlicht, in Irrlicht it must be from 0.0 to 0.999999 !!!

or it's this one:
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=17131
the problem here is that the texture coordinates of the terrain are calculated wrong !!!

Posted: Sun Jan 06, 2008 6:30 pm
by pwierz
Acki wrote:hmm, this looks to me like a texture bug I discovered long time ago... :shock:
either it's this one:
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=13977
the problem there is that in normal case the texture coordinates must be from 0.0 to 1.0
but this is not with Irrlicht, in Irrlicht it must be from 0.0 to 0.999999 !!!

or it's this one:
http://irrlicht.sourceforge.net/phpBB2/ ... hp?t=17131
the problem here is that the texture coordinates of the terrain are calculated wrong !!!
I coded some stuff and I've eliminated this as a possibility. Thanks, though.

What it looks like it might be is that the last column of the texture is bleeding back across into the first column of the same texture. Does this ring any bells with anyone?

Posted: Sun Jan 06, 2008 6:55 pm
by pwierz
I think my theory is correct. If I turn off bilinear, trilinear, and anisotropic filtering I don't get the problem but it's blocky as hell. Does anyone have any solutions for this?

Posted: Sun Jan 06, 2008 6:57 pm
by makripin
Try disabling the alpha channel.

Posted: Sun Jan 06, 2008 7:02 pm
by bitplane
I agree with Frosty Topaz, it doesn't look like a tcoords issue to me. Turn texture filtering off in the material, if the edge goes sharp then your texture splitter is the problem. If not, then it's vertex alpha like Frosty said.

edit:
missed the post above. Try setting texture clamp in the material.

Posted: Sun Jan 06, 2008 7:25 pm
by pwierz
bitplane wrote:Try setting texture clamp in the material.
That was it. Thanks a ton.

Posted: Mon Jul 21, 2008 10:14 pm
by drewbacca
I was having this exact same problem, and also tried setting the texture clamp with

Code: Select all

mtl.TextureLayer[0].TextureWrap = video::ETC_CLAMP;
However, this only solved my problem when using the D3D renderer. Is this not supported in the openGL renderer? I would like to be able to use the same code under linux and would prefer to use openGL.

Posted: Tue Jul 22, 2008 8:27 am
by hybrid
Should work for OpenGL as well.

Posted: Tue Jul 22, 2008 5:49 pm
by drewbacca
hmm... ok. I just wanted to make sure that it wasn't something simple. I'll try and put together a test case to see if I am doing something wrong, or if there is some bug im running into.

Posted: Wed Jul 23, 2008 7:06 am
by ikam
I've exactly the same problem with my terrain pager

ETC_CLAMP works fine with directx but not with opengl.