texture splatting question

Started by
13 comments, last by Raloth 20 years, 8 months ago
Here is the article http://www.cbloom.com/3d/techdocs/splatting.txt and screenshots: http://www.cbloom.com/3d/splatting/index.html Ok, now my question: To make textures blend, the author builds an alpha map. The thing I don''t understand is how does he actually get them to blend in to each other? Does he overlap the textures? Take the situation A A B A A B A A B Does he render A on top of the Bs and Bs on top of the middle As? This would take a lot of vertices if you have an involved terrain, but it''s the only thing I can think of. Can anyone who has implemented this technique give me some direction?
____________________________________________________________AAAAA: American Association Against Adobe AcrobatYou know you hate PDFs...
Advertisement
Texture splatting is based on rendering the terrain within a set radius of the camera, once per a texture. That means several passes, or multi-texturing.

So you should have a single mesh, that is rendered once per a texture, with the alpha values determining the opacity of the texture being render. Each texture/pass can have different UV or scaling to others too.

Of course you can take it further, so if your terrain is split into chunks (quadtree for example), then you can apply texture splatting to only those chunks within a certain radius. Furthermore each chunk can hold information about how many textures it needs splattered, that way you don't have to limit yourself to always rendering x number of textures, but only those that are needed. In addition it means you could also have a large number of textures across the whole terrain, but each chunk might only have say 3 different textures max.

Hope that helps.


[edited by - noisecrime on August 11, 2003 11:17:30 PM]
So I render all the vertices for each texture? I wish this guy would say these things up front instead of making obscure references to them . Can you give me a quick overview of what I have to do to render everything?
____________________________________________________________AAAAA: American Association Against Adobe AcrobatYou know you hate PDFs...
Ooooh nevermind, it finally clicks . Thanks a lot!
____________________________________________________________AAAAA: American Association Against Adobe AcrobatYou know you hate PDFs...
I''ve been working on this same thing for awhile. Please let me know if you get it working. I can''t get my alpha map to line up with my terrain (quadtree). I get sharp edges in lots of places and no matter how I try to stretch or move the alpha map, I can''t seem to get in the right position.

I''m not using the exact method of finding the weights as him. I''ve tried both a 2x2 alpha map where each pixel is the weight at one corner of a tile and a 1x1 alpha map where each pixel is the weight at the bottom left corner of each tile. The 2x2 alpha map gives me better results than the 1x1 but it''s still not right. Anyway, I''d love to hear how you got it working, if you do. Thanks
Thanks!
Use a bigger alpha map.
Between chunk you will have some edges, then you alpha map fonction must take care of edges values from neighbourhood.

Currently I use this method
where alphaMap is a array where each vertices has a materialID.
	// Alpha Map generation	static const int ALPHA_MAP_SIZE = 32;	EcomPtr	alphaTexture[3];	static uint8_t alphaMap[ALPHA_MAP_SIZE*ALPHA_MAP_SIZE];	for(int j = 1; j < 3; j++)	{		if(nb[j] == 0)			continue;		for(int v = 0; v < ALPHA_MAP_SIZE; v++)			for(int u = 0; u < ALPHA_MAP_SIZE; u++)				alphaMap[v * ALPHA_MAP_SIZE + u] = 0x00;		for(int y = 0; y < nbVertexPerRow; y++)			for(int x = 0; x < nbVertexPerRow; x++)			{				if(influenceMap[y*nbVertexPerRow + x] != j)					continue;				if(y > 0 && x > 0)					alphaMap[(y-1) * ALPHA_MAP_SIZE + x - 1] += 0xff/4;				if(y > 0 && x + 1 < nbVertexPerRow)					alphaMap[(y-1) * ALPHA_MAP_SIZE + x] += 0xff/4;				if(x > 0 && y + 1 < nbVertexPerRow)					alphaMap[y * ALPHA_MAP_SIZE + x - 1] += 0xff/4;				if(y + 1 < nbVertexPerRow && x + 1 < nbVertexPerRow)					alphaMap[y * ALPHA_MAP_SIZE + x] += 0xff/4;			}		mDisplay->CreateTexture(alphaMap, ALPHA_MAP_SIZE, ALPHA_MAP_SIZE,			0, Gfx::FormatA8,			Gfx::ITexture::IID, (void**)&alphaTexture[j]);	} 

For each "tile" and each material I add 25% of opacity for the material at this tile for each neighbouring vertex which have this material.

It''s not the best way I think, but for now I have good result.

PS: Sorry for my english.

_______________

Jester, studient programmer
The Jester Home in French
_______________
Jester, studient programmerThe Jester Home in French
Hmm. I''m not sure if I follow you exactly.

If I move my alpha map to a 3x3, then I should be able to have a weight for each vertex and each edge of the tile. If that is what you''re telling me to do, I''m afraid it may be too inefficient. It would then take a very long time to load the terrain, having to generate so many values on the alpha map.

I''ve seen screenshots where people have done it with a 1x1 alpha map and it looks right to me. There must be something else I''m doing wrong.
Thanks!
Chaucer,

I''m not sure what you''re trying to do, but its not the classic terrain splattering that I understand. You appear to be focusing on a purely tile based environemnt, like old 2D games.

The concept of Terrain splattering as asked by the orginal poster was in terms of an entire landscape, where several textures are ''tiled'' across it. In these terms the alpha component is not per a tile, but per the whole landscape (or chunks if divided up).

For example,

1. Terrain mesh based of a 256x256 hieght map
2. 3 tilable textures (grass, mud, stone) of say 512x512 depending upon how detailed you want the texture to be (i.e. how close the camera is going to get to them)
3. 3 alpha textures of 256x256 i.e. 1 pixel per a vertex in the hieghtmap

So the textures may be tiled say 10 times across the terrain mesh, that is 1 tile per 25 vertices. Yet the alpha texture is only tiled once across the whole terrain, giving an alpha value (weight) 1 per a vertex.

This allows you to control the detail level of each texture (its pixel size), the number of times it is physically tiled across the terrain mesh, and each cell/quad of the hieght map can have any mix of the 3 textures.

Using an alpha of a 1:1 ratio with the number of vertices across the terrain means you can simply assign the alpha component as a weight to each vertex, so i don''t think its necessary to actually render it. However if you want finer control then you''d use a larger size alpha map, and actually render the alpha with the texture.
Right. That is the way I'm doing it now. I have an alpha map for each type of texture I use (1 for grass, 1 for rock, etc.)

I render using multiple passes...
For each pass I do

1. Render texture using texcoord1
2. Render alpha map using texcoord2
3. Render lightmap using texcoord2

To calculate texcoord1 and texcoord2, I do

------------------------------------------------------
for(int z=0;z<m_Size;z++){for(int x=0;x<m_Size;x++){float X = (float)x;float Z = (float)z;m_pVertices[vertCount].tex1 = D3DXVECTOR2(X,Z);m_pVertices[vertCount].tex2 = D3DXVECTOR2(X/m_Size, Z/m_Size);}}

------------------------------------------------------
To calculate alpha map, I do
for(int j=0;j<m_NumTexture;j++)  CreateAlphaMap(j, m_Size-1);for(int z=0;z<m_Size-1;z++){for(int x=0;x<m_Size-1;x++){//Since the pixel cooresponds to the bottom left vertex, I find //the four vertices around it by doing this:int current    = GetTextureType(x,z);int left       = GetTextureType(x-1,z);int bottomleft = GetTextureTYpe(x-1,z-1);int bottom     = GetTextureType(x,z-1);for(int j=0;j<m_NumTextures;j++){ float percent=0.0f; if(j == current || j == left || j == bottomleft || j == bottom) {   if(j == current)    percent+=1.0f;   if(j == left)       percent+=1.0f;   if(j == bottomleft) percent+=1.0f;   if(j == bottom)     percent+=1.0f;    percent/=4.0f; } AlphaMapTexture[j]->SetAlphaMapPixel(percent);}}}

------------------------------------------------------

So I have one alpha pixel per each vertex in the terrain or chunk or whatever. I can post a screenshot if you'd like to see the effect I'm getting. I basically get a really good blend sometimes but other times I get a hard edge. I've tried moving the alpha map to fit properly on the terrain since it's 2^N and the terrain is 2^N+1 but its still not working.

Thanks for the help.




[edited by - Chaucer on August 13, 2003 5:49:59 PM]
Thanks!
I do it the same way as you.
The SetAlphaMapPixel(percent); seem strange as you don''t give where to put the percent in the alpha map but anyway.

The difference is that I use chunk of 32*32 tiles (33*33 vertices) so I use a 32*32 alphamap for each chunk. But if your chunk is 1*1 tiles OK.

I have hardedge to, but it''s very rare, and it''s between chunk, certainly billinear filtering of the alpha map, I need to fix it.

_______________

Jester, studient programmer
The Jester Home in French
_______________
Jester, studient programmerThe Jester Home in French

This topic is closed to new replies.

Advertisement