Texture Splatting for Terrain Texturing

Started by .jayderyu, January 30, 2010, 06:40:26 PM

Previous topic - Next topic

.jayderyu

I was reading up on Oddlabs Procedurality api. I thought it was nifty, while I was reading their talk about game terrain and looking through the api. I noticed there was nothing on texturing. So after some digging around I found out something called Texture Splatting. Visually it meshes with Tribal Trouble and other nice terrain.

http://tribaltrouble.com/screenshots?id=04(I use to use some of their early screen shots as wall paper. When it was just terrain).

Here is I thought a descent reference to how it works.
http://blog.nostatic.org/2007/11/3d-landscape-rendering-with-texture.html

Heres the jist of it as an example.
create a plane say 256x256 by 2units(as meters). That's  512 meters. though size doesn't really matter. Set the UV to tile a textures.

create 2 or more alpha maps. Let's say circles. One is a white circle that slow fades to black. The other is reverse that. Black circle slowly fading to white.
This is a 0-255 alpha map that is translated to a 0-1 as needed.

get 2 textures. one is bumpy grass that is 64x64. or bigger/less. regardless it's a detailed texture that will be tiled. the other can be dirt.

render the plane. texture the plane with the tiled dirt using the white circle alpha map. this results in a dirt circle on the first pass.
on the second texture pass. render the tiling grass texture with the black circle. what happens is that the grass is rendered onto the white alpha values of the surface. Now since both have some grey fade in between both texture will visually create a smooth transition.

I've gone over Object3D. While I could find setAllTextures(String Texture, String bumbmap). I couldn't easily see any way to do alphamaps.

maybe JPCT has something that can do this, but I don't know where I would look.


EgonOlsen

The alpha channel is part of the texture. You can create a new texture out of the dirt texture and the alpha map with the usual Java2D image methods and create a new Texture-instance from that. Or put them both into different texture stages and use an appropriate blending mode. To render the base texture independantly, you'll need at least two passes, which means that you'll need two different Object3Ds using the same mesh but different u/v-coords and textures. You can set textures on a per polygon level using the PolygonManager or you can assign them for the whole object using setTexture(). Look out for the methods that take a TextureInfo instead of an id.
Or use vertex alphas instead like the terrain demo does. It limits it's usage to display different height, but that's just a limitation of the demo, not of the method.

.jayderyu

#2
First. I'm a bit texture stupid :P I understand how UV works and alpha channels. past that i'm a bit duh. So If I make mistakes on my undestanding in my following comments please bear with me :P


"Or use vertex alphas instead like the terrain demo does. It limits it's usage to display different height, but that's just a limitation of the demo, not of the method."
I think I'll try this one. Looking at the terrain video. This effect looks similar. It also looks like it has 3 textures applied. so I assume it can handle more.


"The alpha channel is part of the texture. You can create a new texture out of the dirt texture and the alpha map with the usual Java2D image methods and create a new Texture-instance from that."
Well tiling the texture with alpha set to it would just alpha the tile. Which wouldn't really work.

"To render the base texture independantly, you'll need at least two passes, which means that you'll need two different Object3Ds using the same mesh but different u/v-coords and textures."
Sounds inefficient. :\

"You can set textures on a per polygon level using the PolygonManager or you can assign them for the whole object using setTexture()."
Sounds interesting, but it doesn't sound like it would blend to other textures. Though I suppose you can make a blended texture.

I'm going to certainly try the vertex alpha.

edit:
umm, can't find the source code example for the terrain demo.

EgonOlsen

It's in the zip. You can find the link in the thread that has the screen shots too.

.jayderyu

I finally found the thread in question. http://www.jpct.net/forum2/index.php/topic,1479.30.html

the funny thing is that. what the poster was taking about. was along the lines I was thinking of too. That would explain why the vertex shading works well. Thanks for the heads up. Now I just need to make the maps in question for the terrain alpha vertex....

you know. this procedural height mapping, terrain texturing and geomipmapping is getting out of hand for a simple prototype :\

though know how this vertex stuff is really important regardless.

.jayderyu

I have a question about Object3D and distance. Is there a way to set it up to automaticly change to a different mesh or object on distance. I was studying up on geomipmapping. Since there is no way to manually alter the mesh. I was thinking of swapping the mesh or Object3D with another. I haven't worked on animation at all, but I suppose it would be a form of animation on distance. So looking through the Animation class I couldn't see anything in regards to distance. What I have learned is that that if there isn't something apparent JPCT still might have something that can do it.

.jayderyu

#6
So I was trying blend mode when setting texture. PolygonManager.setTexture(polyId, textureId, BLEND_MODE);. what I found is that the two brightish textures were super dark. In the distance they look near black. I was wondering how to avoid that. Also I was wondering how to use MODE_ADD_SIGNED to achieve gradual or strong blendings of different textures.

Also I noticed that terraindemo uses two terrain objects to achieve a certain blending effect. I'm not going to have to do that to get similar effects. or do I?


Edit:
just to be clear on IVertexController.getSourceMesh(). This is just a copy of the SimpleVector[] mesh. As I'm looking through the geomipmapping I might need to use it as reference to build the LOD meshes. So I though I would use the VC to pull a copy of the Vertices out.

EgonOlsen

I never really understood BLEND myself. You can look at the formula in the OpenGL documentation to see what it actually does, but i never got a feel for the outcome. I've never ever used it except for the detail textures in the terrain demo (i'm not sure if the downloadable version supports that). Just try some other mode.

About the two objects: The terrain demo uses one object mapped with only the base texture and one that contains the rocks and the sand (under water) as well as the vertex alpha values. As long as you are using this approach, you need those two objects. There are other ways (shader based for example) that may not need it, but i've never used them.

getSourceMesh() returns the SimpleVector[] copy of the mesh that the controller holds. This isn't the mesh that the object itself uses. However, as long as you are manipulating your mesh with the controller only, the controller's mesh and the internal mesh of the object will be in sync. That said, do you really need this geomipmapping stuff? Today's hardware is pretty fast when it comes to pushing polygons. It's usually not needed to use lower res models unless your terrain if really large.

.jayderyu

Quote from: EgonOlsen on February 06, 2010, 08:33:09 PM
I never really understood BLEND myself. You can look at the formula in the OpenGL documentation to see what it actually does, but i never got a feel for the outcome. I've never ever used it except for the detail textures in the terrain demo (i'm not sure if the downloadable version supports that). Just try some other mode.
ahh it's part of the OpenGL stuff. I'll will take a look at that. I thought it might be a JPCT thing.


Quote from: EgonOlsen on February 06, 2010, 08:33:09 PM
About the two objects: The terrain demo uses one object mapped with only the base texture and one that contains the rocks and the sand (under water) as well as the vertex alpha values. As long as you are using this approach, you need those two objects. There are other ways (shader based for example) that may not need it, but i've never used them.
I went looking over the code after this comment. I finally get what's fully going on. I originally thought that the setVertexTransparency(poly, vertice, alpha) was in relation to the a new texture over the old texture. When what's happening is that only part of the object is transparent. Allowing the object underneath to be seen. I had made a mistake in regards to how that works. I think I have a clearer picture.

Quote from: EgonOlsen on February 06, 2010, 08:33:09 PM
getSourceMesh() returns the SimpleVector[] copy of the mesh that the controller holds. This isn't the mesh that the object itself uses. However, as long as you are manipulating your mesh with the controller only, the controller's mesh and the internal mesh of the object will be in sync. That said, do you really need this geomipmapping stuff? Today's hardware is pretty fast when it comes to pushing polygons. It's usually not needed to use lower res models unless your terrain if really large.
ok thanks. I know it's safe to use now.

I was originally wondering that myself. After a few positional tests of the camera to try a capture the feel of different game styles I noticed a strong performance difference for compileandstrip() in HW mode working with 512x512.
Being low and in the scene produced ok framerates. I suppose there is a lot of culling going on. however as scene goes up towards mountain peaks or towards corners of the scene fps drops a lot. While at the moment I'm not looking to design a flight sim I can see a significant difference. Though I haven't tried splitting the terrain into octrees yet. It's still a single big mesh. I also use 512x512 textures and think that maybe even the locations that are very far off are using the full res texture instead of mipmapped. It still probably worth it to break the map into patches for the mipmapping to work. Though I could be wrong.