texture atlas , adapt UV

Hello.
I solve the problem of tiled texture inserting only the non tiled textures in the atlas, and separating the tiled textures.
Now i have an atlas that contains only non tiled textures
My problem now is:

I have an atlas texture that contains two textures of width 512 .
and one with height 256 and one with heigh 512.
The texture atlas have a width of 1024 and a height of 512.
Now:
i have a UV on the first vertex of first texture U:0,7 , V:0,4
and i have an UV on the second vertex of second texture of U:0,4 , V0.8.
How i can transform these examples, of vertexes for working with the atlas UV?

Thanks.

Your atlas can described in two ways : either in UV space (ranging from 0 to 1 in both coordinates) or in texel space (ranging from 0 to 1024 in width (x) and from 0 to 512 in height (y)).

To transform texel space to UV space, all you have to do is divide by texture size (width for U, and height for V).

Now supposing your first texture is on the left part of your atlas, its texel space is ranging from (0,0) to (512, 512) - it’s UV space range would be (0/1024, 0/512) to (512/1024, 512/512) ; that is to say (0,0) to (0.5, 1)

Supposing your second texture is on the right part, aligned to the bottom, its texel space is ranging from (512,0) to (1024, 256) - it’s UV space would be (512/1024, 0/512) to (1024/1024, 256/512) ; saying (0.5, 0) to (1, 0.5).

This gives you the ranges in UV space of your subtextures. As you want to transform you sources UVs (in range (0,0) - (1,1)) to these ranges, you need to scale them, to match the subtexture size, and offset them, to match the subtexture location.

The subtexture location (or offset) is the minimum value of the range described above :

  • (0,0) for texture one
  • (0.5, 0) for texture two

The scale factor is the (width, height) of you subtexture :

  • for texture one, (0.5, 1) - (0,0) = (0.5, 1)
  • for texture two, (1, 0.5) - (0.5, 0) = (0.5, 0.5)

To finally get to the point, you first vertex with UV (0.7, 0.4) would give you (0.70.4+0, 0.41+0) for texture one.

Your second vertex with UV (0.4, 0.8) would give you (0.40.5+0.5, 0.80.5+0) for texture two.

Hope you get the point, I tried to be as explicit as I could :stuck_out_tongue:

very thanks.
you have been realy clear.
And if my UV are < 0 or > 0? how i can solve?
Is a good choice create a custom shader that does it?
the game’s worth the candle?
because i have a lot of tiled/wrapped textures in my sketchup importer.

Thanks

ps.

i’m read another time, but i’m not very clear this:
(0.7, 0.4) would give you (0.70.4+0, 0.41+0) for texture one.

why 0.7 * 0.4??? there are two 0.4 one in the first and one in the second vertex

You’re welcome !

For more involved information, you could take a look at this whitepaper :
ftp://download.nvidia.com/developer/NVTextureSuite/Atlas_Tools/Texture_Atlas_Whitepaper.pdf

Tiling textures in an atlas is more complicated, they involve some arithmetic in shaders, and to be careful with gradient selection for texture sampling.

My recommendation would be not to bother with it until you can explicitly measure that you could increase performance with making an atlas of your tiled/wrapped textures.

[quote]
i’m read another time, but i’m not very clear this:
(0.7, 0.4) would give you (0.70.4+0, 0.41+0) for texture one.

why 0.7 * 0.4??? there are two 0.4 one in the first and one in the second vertex
[/QUOTE]
Sorry that’s a mistake, you should read 0.7*0.5+0

thanks again Nicolas .
I have an idea , is possible draw on a frame buffer in opengl the wrapped or tiled texture entirely with his UV, saving the result image, and send it to the atlas?
The problem is :is possible in some way take from the UV the size of the resulting texture?
Because I’m not can process all geometry for this.

by.

Sure you can could this way, this is called ‘texture baking’.

Drawing the texture in the framebuffer is the easy part, what’s more difficult is to create a set of UV coordinates to allow to do so. The generic name of this problem is ‘mesh parameterization’.

Without knowing you specific needs, all I could do would be to give you generic pointers that are complicated to setup, and still active research topics.

Really, I’ll settle on my advice to let your tiling textures alone, unless you’re willing to spend vast amounts of time learning these topics.

Cheers,

ok, I understand.
Thank for the advice.
My problem now is to recognize what are wrapped/tiled and what are not.
I’m creating this function in c++:


bool CMesh::IsTiled()
{
	std::vector<TEXCOORD*>::iterator itBegin =	m_vTextureCoord.begin();
	std::vector<TEXCOORD*>::iterator itEnd =	m_vTextureCoord.end();

	for(;itBegin != itEnd; itBegin++)
		if(abs((*itBegin)->U) >1 || abs((*itBegin)->V) >1)
		return true;
	
	if(m_pMaterial->GetTypeMaterial() == eTextureDouble){
		std::vector<TEXCOORD*>::iterator itBegin =	m_vTextureCoordBack.begin();
		std::vector<TEXCOORD*>::iterator itEnd =	m_vTextureCoordBack.end();

		for(;itBegin != itEnd; itBegin++)
			if(abs((*itBegin)->U) >1 || abs((*itBegin)->V) >1)
			return true;
	}		
	return false;
}


but i see that this is wrong:


abs((*itBegin)->U) >1

i removed the abs():


if( ((*itBegin)->U) >1 || ((*itBegin)->U) <0)
return true;//is tiled/wrapped

the problem is that i have some texture UV of U = -0.4 V = 0.2 and with your algorithm for the atlas it work fine !
why?
the texture UV don’t be from 0 to 1 ?

this is the code for read from sketchup api the uv:


	m_pApi->ImportVertexUV(&fu, &fv, &fw, &fub, &fvb, &fqb);
	TEXCOORD *ptUV = new TEXCOORD;
	ptUV->U = fu  ;
	ptUV->V = 1- fv ;//this is added from me without explanations , only 
for :"so 'works"  BAD!!!!
       
	ptUV->W = fw;
	
	vVectorUV.push_back(ptUV);

//ecc...
//ecc...

how i can recognize uv and wrapped texture?

thanks again.

Hello.
In my sketchup importer with atlas (thanks you) i must use the double texture material , that is a geometric object that has two faces , one with one texture and one with an other.
For this double face textured I save in the atlas a picture with two subimages one on the top of other(because I must assure that each of two texture live in the same atlas , because i can have more than one atlas , and if a double face object have a front texture in an atlas and a back texture in another there are a big problem), one for the front face and one for the back face.
My problem is that i would transform the UV of the geometric object(a face for example) for adapt the tex coord to the model both for front face coord and back face coord.
I have in the shader:
float3 TextFront TEXTCOORD0;
float3 TextBack TEXTCOORD1;
and these coords are imported from the sketchup model .

Now my problem is to transform the uvs (back and front) to adapt the texcoord to the atlas like the previous post.

For the front face i change the vOffset to 206 and work fine , the problem is for the Texture B , i set a voffset of 0 but I’m not clear how i can transform the uvs correctly .
may be that i must change some other parameters in the function that calculate the offsets?

this is my image
Image
is like an atlas inside another atlas?
Thanks.