Terrain Texture Splatting???
Blitz3D Forums/Blitz3D Programming/Terrain Texture Splatting???
| ||
Has anyone read about or understand 'texture splatting'? http://www.cbloom.com/3d/techdocs/splatting.txt Specifically, how it works with terrains. I have read several articles (none with example code :( ), but cannot get a grasp on how this would work with Blitz. It sounds like they are making multiple render passes, maybe 1 pass for each unique texture using alpha masks to leave transparency where the texture does not belong. But then, wouldn't you need to build the alpha masks on the fly in real time??? Also, it seems you would need a separate camera for your terrain so as not to render everything else every frame. Can this work in Blitz?? Thanks, MK |
| ||
With the advent of vertex alpha support in Blitz, there is no need to create alpha maps on the fly. You can render it the right way. And no, it doesn't require multiple passes... well not many. What you need to do is render your sky and terrain in one pass, and then your level entites in a second pass. Then, for your each triangle on your terrain where you want one texture to blend into another, you simply add two or more triangles to the terrain which exactly overlap, with the first one being opaque, and the ones to be layered on top of it being added in the order you want them drawn, and with the appropriate vertex alphas. This works because Blitz draws the triangles in the mesh in the order in which they are added to the mesh. If you want, you could even just stick all the first pass triangles in the mesh first and then add all the second or third pass triangles to the end, but you can intermix them if you want as long as each individual set of triangles is added in the right order. And no you don't need more than one camera. All you need to do is do a hideentity and showentity for every object in your level every frame... Which mark optimized a ton not too long alog making hiding and showing just about as fast as setting a variable to true or false. Of course to do this you need to keep a list of your entities, but you should be doing that anyway because that is the best and cleanest way to do things. |
| ||
Oh and btw, this is for terrains you make yourself out of meshes, not for Blitz terrains. There's no way to do vertex alpha effects witht he built in terrains. Those terrains are really slow anyhow. My terrain system for example 2-5x as fast, with 5x as much detail, and you can tile textures on it and rotate them. Now that vertex alpha is in perhaps it's time for a re-write to get rid of that cracking issue and support texture splatting instead of tiling textures which requires really high res textures to get a good level of detail and as a result also limits how fast the terrain can go because of the actual number of tiles I have to make the terrain out of. |
| ||
Thanks for the reply Shawn. I understand what you are saying, but a couple of questions. I thought I read there is a problem with z-order with vertex alpha. Are you saying that by adding the triangles in the right order, this is avoided? Couldn't this approach double or more your poly count? Also, I just realized, this probably requires unwelded verts, right? Thanks, MK |
| ||
I don't know much about the whole vertex alpha thing but the recent addition of support for the second UV set in Ultimate Unwrap adds a lot of possibilities as far as texturing terrain. As soon as I clear off some of the tasks on my plate right now I will be writing a tutorial for Ultimate Unwrap in which I use the 2nd UV set to texture terrain. The gist is all about multiple texture layers: a main non-tiled texture for color, a tiled detail texture over that, and then a third layer with alpha transparency placed using the 2nd set of UV coordinates. |
| ||
We experimented with that on Mechcommander 2, then to a variation of that technique that saved out a custom texture library for each level (major cd-space hog mode) then went to a single giant (1536 x 1536)hand-painted land jpeg (divided into 256x256 textures at runtime) plus a small tiled detail texture. While it was fuzzier, it saved a huge wad of texture space for more important things. It's a great system if you use a lot of randomly generated terrain, but the draw overhead is pretty fierce. |
| ||
"Couldn't this approach double or more your poly count?" It could, but you can make large areas with just one texture, and thus one layer and then only make a thin border between them as a transition area and then it would only increase poly count of 10% or so. "Also, I just realized, this probably requires unwelded verts, right?" It requires one surface per texture, per entity, so if your terrain is divided into tiles that ar 10 meters across, and one has two textures on it, it will need two surfaces. As for unwelded vertices, I'm not sure what you mean exactly by that. If you mean that you intend to store all the textures as part of one big texture and tile them by having unwelded edges on every tri/quad, then I would edvise against that. I wasn't thinking about the seprate textures thing before. What you need to do is have at least one surface per texture per entity which the terrain is made up of, but each entity only needs surfaces for those specific textures it uses. So usually that means each entity would have two surfaces, though it may go as high as three or four surfaces. I suppose since the major cost is surfaces and not entities that this reduces my prediction for the amount of savings I would get over my current method, but I think that I could probavbly still save at least 2x if not 6x the surfaces with this method over trying to make each entity have a non-tiling texture. Cause if I can make the texture tile a lot, then I can use lower res textures and make the entity as wide as I want instead of trying to keep it narrow and use a 1024x1024 texture to try and eek as much detail into is possible. Anyhow, so you would like have a tile in your terrain with two surfaces. The surfaces have to be added in the order which you want the textures drawn for that whole tile cause that's the order they'll be drawn in. So like you have a surface of rock, and grass. Each texture scaled to tile 8 times across the object. Then you use vertex alpha on the grass layer to blend with the rock layer. Then you delete all polygons in the grass layer which have all 3 vertcies at alpha 0, and all polygons in the rock layer which have all three vertcies at alpha 0, since those will be covered up completely by the other texture. As long as your transition is pretty tight from one texture to the other you should only get 10-20% extra polygons where the overlap is. And that's it. Blitz will then render the obejct in surface order, and within each surface in triangle order. But teh triangle order doesn't matter if you're not trying to blend triangles in the same surface. |
| ||
Well, I tried this theory out and I've encountered several issues with vertex alpha. Here is my test program (it is REALLY CRAPPY CODE because I was just kludging on the fly, trying out the theory, so BE NICE!). (Textures/Heightmap included) http://mywebpages.comcast.net/hnorse1/test_splatting.zip The docs say you must set EntityFX with 32 to get vertex alpha to work. I found that I also had to set flag 2, Use Vertex Colors, also. I have two surfaces. The primary surface containing the base texture, and the second surface that has a patch or splatting texture. Order is really important. You need to add the splatting surfaces first or it won't show up. Hence the butchering of my code. Obviously in a real splatting code you would create the splats based on height and slope. Anyways, it seems that the primary Surface now has some transparency although all of its vertices have vertex alpha set to 1.0! Move the camera left and right, you can see through hills. Also, I originally was contemplating unwelded vertices and being unacheivably skillful at setting their uv coords to map a single combination texture to all the splats. Only one surface, ooh, ahh! But it dawns on me that without layers, what would it blend with??? Duh! I have a real reservation about this approach because it will require probably a minimum of 3 surfaces, if not four, to get the appropriate terrain detail, as Shawn mentioned previously. If this were a single static terrain mesh, that would be OK. But with a tiled terrain engine, you will now have 3-4 surfaces per tile - easily 300-1000 surfaces. That Won't work! The option is to make the tiles bigger and have less tiles, but for Dynamic Level of Detail, you can only get away with rebuilding tiles 32x32 in real time. Also, I would also now have to rebuild all of the surfaces for the splats. Sure would be nice to have a deletetriangle command without clearing the entire surface. Now that I think about it, I was reading an article that suggested splatting only the near tiles and using a colormap and single detail texture for far tiles, since detail far off in the distance won't be important. That would reduce the number of surfaces dramatically, especially if it was limited even more to only the tiles in the view area (EntityVisible). Anyways, anyone else have any ideas, input, theories, suggestions, solutions, innovations, inspirations, contemplations, ascertations, interpretations... Thanks, MK |
| ||
" but for Dynamic Level of Detail, you can only get away with rebuilding tiles 32x32 in real time." You should not be doing dynamic level of detail if you value your framerate! :-) That will kill your FPS a lot faster than adding extra surfaces will, that's for sure. :-) If you use static levels of detail like I do, but set it so that the distance the highest level of detail is used is pretty far out then you can't see the snapping much. Blitz is just not designed properly for a morphing terrain engine. You need geomipmapping support for that, which I think requires like DX8 or something. I'll try your test out now and report the results I get. Also, while perhaps you may need to have 3 or 4 diffrent surfaces per tile in some instances, surely you won't need to have that much variation on more than 30% of the tiles in your terrain or so. |
| ||
Okay tested it. Crap. I know what the problem is, and I don't like it. It's not the vertex alpha. That's just fine. It's that Blitz is not zbuffering. I totally forgot about zbuffering being disabled when you disable transparency, but for the record I do recall mentioning to Mark that we needed to be able to enable zbuffering when rendering transparent objects around the same time I talked to him about adding vertex alpha, for this reason, and for the reason of rendering particles onto the scene with alpha. Without zbuffering you cannot fix this issue. I have a feeling Mark forgot to enable it and nobody has been using this feature so nobody complained. I'll send him an email pointing him to this topic. |
| ||
Okay Mark has been emailed on the issue. |
| ||
Shawn, If you use static levels of detail like I do, but set it so that the distance the highest level of detail is used is pretty far out then you can't see the snapping much. This approach works really good for a fixed size terrain, but I am trying to make my terrain infinate. This requires using a fixed set of tiles and modifying them to look like the current terrain view. Thanks for looking at the example and the input. MK |