Texture splatting question(s)

Started by
14 comments, last by Phil_321 19 years, 8 months ago
I'm trying to implement texture splatting based on Charles Bloom's paper: http://cbloom.com/3d/techdocs/splatting.txt After reading it appox. 50 million times, I have a good grasp of what he's doing. I've a question though (probably have a few more before I've got it up and running) For each quad of the terrain Bloom puts 4 pixels into an alphamap that covers the entire terrain, for each texture. Ie. for a 256x256 heightmap there will be a 1024x1024 alphamap for each texture. Doesn't this sort of defeat the purpose of splatting(which I gather is good detail without using lots of memory), as you will end up with huge (alpha)maps consuming lots of memory consumption.
Never accept failure when dealing with things that are within your control.
Advertisement
Yes it does. I opted to go with only 1 texel per point on my map. I also went with 16 bit textures, since I couldn't really tell the different between 32 and 16. A 256x256 texture at 16 bits is only 1 megabyte.

You can get around this by using pixel shaders. This lets you pack four alphamaps (one for each channel) into a single texture. So now for a 256x256 patch you are down to 1 megabyte instead of 4 if you have 4 layers. Compression can help even more.

Don't worry about it too much. Most modern cards have at least 128 mb of memory physically on the card, and have even more available for textures. Keep in mind that it doesn't all have to be in the card at once. You can swap textures in and out from system memory as you need without too much of a performance hit.
____________________________________________________________AAAAA: American Association Against Adobe AcrobatYou know you hate PDFs...
O.K., I think I'll go with one pixel per quad too.

I was also wondering why Bloom splits the terrain up into "splat chunks"?
I have my terrain divided up into a quadtree for rendering, but I don't see why Bloom splits it up when creating his alphamaps for splatting. Couldn't you just go through the entire heigtmap and determine the alpha values for each alphamap without breaking it into chunks first?
Never accept failure when dealing with things that are within your control.
Don't base it off of the heightmap. You are ruining a perfectly flexible solution by doing so. I made a simple editor that allows me to place different textures wherever I want and it's great.

I would recommend ignoring Bloom's article. It's confusing and doesn't even say what he's really doing.

All it is is a bunch of alphamaps that say what texture goes where. Forget the entire tile-blending-weight-whatever thing he had, it doesn't even make sense.

The reason the alphamaps are divided up into chunks is to save memory. Sure you could have eight 1024 x 1024 alphamaps, but some of them might only have data in one 32 x 32 area, and the rest is wasted.
____________________________________________________________AAAAA: American Association Against Adobe AcrobatYou know you hate PDFs...
Thanks for the help Raloth. I've got the alpha maps created now but I'm not sure how to combine them with the color maps when rendering.
I have the following textures:
grass grass_alpha
rock rock_alpha
ground ground_alpha

I'm not sure how to go about rendering all this with 2 texture units(gf mx440). Any ideas?
Never accept failure when dealing with things that are within your control.
Hi, Phil.

I've also been looking into texture splatting, and especially Bloom's article, (which I, also, had to read about ten times).
I have the quadtree-based terrain.
According to Bloom, (or at least what I gathered he was trying to say), you should create one index buffer per texture (per chunk).

Then, follow these steps during rendering:
1. Render the base texture, (usually just the most common texture).
2. For each chunk, bind the chunk's alphamap into one texture unit
3. For each texture, (grass, rock, sand, whatever), bind the texture. Then render the index buffer associated with that texture.

Note: I haven't yet implemented it myself, (stopped the terrain-thingie shortly, and am now doing something else), but I will be doing it soon enough in the future. So, I'm interested in hearing about your results. Keep me posted on how it works out.

I hope this was helpful!
O.K. James, I might try that.
You're saying to render the most common texture and blend the others on.
What about rendering the textures one by one (with their alpha maps), would this work?
Well I suppose I'll find out, once I remember how to do multitexturing. :)

I'm a bit rusty, I'm only getting back into it programming after about 6 months.
Never accept failure when dealing with things that are within your control.
O.K. I layed a base grass texture over the entire terrain.

Now I want to combine my rock texture and rock alpha maps, and render them on top of it.
The problem is the rock texture has RGB components but the alpha map texture only has one component.
I created it with this:
glTexImage2D(GL_TEXTURE_2D, 0, 1, width, height, 0, GL_RED, GL_UNSIGNED_BYTE, data);

// Bind rock texture to texture unit 0glActiveTextureARB(GL_TEXTURE0_ARB);rockTex.Bind(GL_TEXTURE_2D);// Bind alpha map to texture unit 1glActiveTextureARB(GL_TEXTURE1_ARB);rockAlphaTex.Bind(GL_TEXTURE_2D);glActiveTextureARB(GL_TEXTURE0_ARB);// Set up the texture environment to combine the two textures so that the rgb of tu0 and the alpha value from tu1 are used when renderingglActiveTextureARB(GL_TEXTURE0_ARB);glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE);glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ARB, GL_REPLACE);			// This section is probably all wrong!glActiveTextureARB(GL_TEXTURE1_ARB);glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB);glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS);glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_TEXTURE); glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ARB, GL_MODULATE);


The terrain ends up covered in a very darkened rock texture even though there's barely any rock in the terrain.
Never accept failure when dealing with things that are within your control.
I wrote a simple texture splatting demo in OpenGL a long time ago. It didn't work very well and wasn't very flexible, but it got the job done.

Demo
Source

There are a lot of things wrong with that code since I was new to OpenGL at the time, but it should at least help you get your render states right. I am currently working on an article about texture splatting in Direct3D. It shouldn't be too hard to be able to understand what it's doing and port it to OpenGL.
____________________________________________________________AAAAA: American Association Against Adobe AcrobatYou know you hate PDFs...
While I haven't looked into the technical details, I think UnrealEd terrain texturing may work in a similar way. When you add a texture layer to the terrain you then have to paint where you want the texture to show, allowing you to blend it into existing layers. Very good for coping with steep slopes and cliffs, even though its just a height field, you can paint an appropriate texture over the cliff area and you don't get the horrible texture stretching if you just try and apply a texture over the entire height field.

This topic is closed to new replies.

Advertisement