adding more splatting textures - newb -

tod

05-02-2008 20:20:57

I've tried and tried to understant how in hell can I add more textures for splatting over the terrain. I am a newbie in this 3d stuff so maybe the questions are stupid, but then again I'll give it a try.

I am looking for something like this: have a folder with splating textures that are loaded at runtime, chose whatever texture you want and paint with it.
I see that the splating textures are specified in the material file? Is this requiered? Maybe I can modify the material at runtime and add more?
Also it seems to me that the more textures you add the more passes you add. Is this right? I mean this would mean that you are pretty much limited to 6 textures which seems odd to me. If this is the case, is there a way to, lets say, create a big texture that is applied over the terrain when saving, to skip some processing when painting is not needed, like in the final game? Maybe after painting with 6 textures, I can create that big texture, paint on top of it with another six, and so on?

Thanks in advance and please dont be gentle! :wink:

CABAListic

05-02-2008 22:40:04

I am looking for something like this: have a folder with splating textures that are loaded at runtime, chose whatever texture you want and paint with it.
I see that the splating textures are specified in the material file? Is this requiered? Maybe I can modify the material at runtime and add more?

Simply put, the material defines the looks of your objects. The terrain is just another object in the scene, and the splatted textures are its look, so the splatting is done via material. You can of course use a dynamic material created by your code, after all the material scripts are parsed and translated to an instance of Ogre's Material class, anyway.

Also it seems to me that the more textures you add the more passes you add. Is this right? I mean this would mean that you are pretty much limited to 6 textures which seems odd to me.
A single pass has a limited amount of texture units it can handle. The theoretical upper limit for a shader model 2 based pass is 16, but in reality many cards will have fewer actual texture units, so they'll break up the pass in two internally. In any case, with 16 texture units you can, in theory, use 12 splatting textures per pass, the rest of the texture units are needed for the coverage maps. If you need more, you will need to add more passes, that's just the way it is. Obviously, the more passes you use, the more costly it will be, so your performance decreases. How many splatting textures you can use depends on the power of your graphics card. 12 textures over 2 passes should be no real problem for a 6600GT or better.

If this is the case, is there a way to, lets say, create a big texture that is applied over the terrain when saving, to skip some processing when painting is not needed, like in the final game? Maybe after painting with 6 textures, I can create that big texture, paint on top of it with another six, and so on?
ETM does offer the possibility to create such a texture, look at SplattingManager::createBaseTexture. However, since the texture has a limited resolution and is stretched over the full terrain, it will look considerably worse than actual splatting (that's why splatting is used in the first place).

SongOfTheWeave

05-02-2008 23:01:15

I am looking for something like this: have a folder with splating textures that are loaded at runtime, chose whatever texture you want and paint with it.
I see that the splating textures are specified in the material file? Is this requiered?


It sounds like you need to take a bit of time and learn the basics before you dive in here. I can vouch, it will save you a great deal of frusteration.

Concepts you should make sure you have solid in your head:

- How does geometry get on the screen?
- - See Ogre::Entity first then broaden out to cover Nodes, MovableObjects, SceneManagers (I suggest this order because I think it would make the most sense in that order, not because this order is at all fundamental to the architecture.)

- How do textures get on the geomety?
- - See Ogre::Material (and MaterialPtr and MaterialManager) and read the manual section on material scripts. I found it helpful to look back and forth between the section on material scripts in the manual and the Ogre::Material API page because it helped me to correlate in my head that they were resulting in the same thing, even though they oft use different grammar.

-----

As for how to add/change your splatting textures at runtime, look at the Ogre::Material API. You will need to programmatically modify your Material during runtime.

Note the following methods:

Ogre::Material::getTechnique(int)
Ogre::Technique::getPass(int)
Ogre::Pass::createTextureUnitState(String)

MisterMayhem

05-02-2008 23:37:05

Six textures for splatting is quite a luxury, before this neat addon sprung up we mostly had one :).

I made my terrain a bit more flexible by manually loading the 6 textures, and giving them each a name that the material expects.

In the material I don't use file names for the splatting textures, but instead I use "terraintexture_1", "terraintexture_2" etc.

So I load the textures manually and give them the 6 names, but the neat thing is my code decides the actual textures that are manually loaded, so I can use my editor to specify which texture file goes to which layer.

My key function for doing this is:

// ----------------------------------------------------------------------------
void Terrain::_LoadLayerTextures(void)
{
// Load (up to) 6 manual layer textures
for (int i=0; i<6; i++)
{
if (mLayerTextureNames[i] != "")
{
Image LayerImage;
LayerImage.load(mLayerTextureNames[i], "General");
TexturePtr LayerTexture = TextureManager::getSingleton().loadImage
("terraintexture_" + Ogre::StringConverter::toString(i+1), "General", LayerImage);
}
}
}


Of course you'd have to fill in some pieces, but you can see what I'm doing. Loading the 6 textures specified in the mLayerTextureNames[] array, and giving them the names expected by the material.

My editor lets the user choose a different texture for each layer on the fly, but the reality is that the terrain must be unloaded and then reloaded with each such change. the manual textures are unloaded and then reloaded, as is the material. The brief pause to do this is well worth it.

kungfoomasta

05-02-2008 23:42:03

The pain is in organizing the material at runtime, given the ability to add/remove/change splatting textures.

The ideal scenario would be to allow the artist to add, remove, and replace textures within the editor. This means you have to manage the material, adding and removing passes and texture unit states on the fly. That way an artist can choose to use only 3 textures for a terrain, or 8, or 16, and not even have to think about any implementation limitations. Its not as simple as looking at the Ogre API docs. :P

I'm not trying to be negative, but a while back before I got side tracked I was trying to implement the functionality listed above. Its not very trivial to design.

CABAListic

05-02-2008 23:48:42

I will probably include a sample implementation of a dynamic terrain material in ETM v3 which does exactly that. I suppose it may help people getting started, although for advanced uses you'd still have to come up with your own material system. Though splatting can be implemented more or less generically, there is no way a single material could cover all other eventualities that a material might need to be doing, especially considering shadows.

tod

06-02-2008 09:36:46

Thank you all for your answers, I will be getting back with other nagging questions after I dive in the code some more :twisted:

Nauk

06-02-2008 10:01:47

For simply adding more textures I didn't find any other way than editing the ETTerrain.material and the PSSplat2.cg adding an extra coverage map:

ETTerrain.material:

material ETTerrainMaterial
{
technique
{
// primary splatting technique, requires PS 2.0
// has issues with OpenGL rendering, though...

pass
{
// splatting pass

lighting off

vertex_program_ref ET/Programs/VSLodMorph2
{
}

fragment_program_ref ET/Programs/PSSplat2
{
param_named splatScaleX float 192
param_named splatScaleZ float 192
}

texture_unit
{
// first coverage map, dynamically managed
texture ETSplatting0
}
texture_unit
{
// second coverage map, dynamically managed
texture ETSplatting1
}
texture_unit
{
// third coverage map, dynamically managed
texture ETSplatting2
}

// splatting textures
texture_unit
{
texture splatting0.png
}
texture_unit
{
texture splatting1.png
}
texture_unit
{
texture splatting2.png
}
texture_unit
{
texture splatting3.png
}
texture_unit
{
texture splatting4.png
}
texture_unit
{
texture splatting5.png
}
texture_unit
{
texture splatting6.png
}
texture_unit
{
texture splatting7.png
}
texture_unit
{
texture splatting8.png
}
}


PSSplat2.cg:

void main
(
float2 iTexCoord0 : TEXCOORD0,

out float4 oColor : COLOR,

uniform sampler2D covMap1,
uniform sampler2D covMap2,
uniform sampler2D covMap3,
uniform sampler2D splat1,
uniform sampler2D splat2,
uniform sampler2D splat3,
uniform sampler2D splat4,
uniform sampler2D splat5,
uniform sampler2D splat6,
uniform sampler2D splat7,
uniform sampler2D splat8,
uniform sampler2D splat9,

uniform float splatScaleX,
uniform float splatScaleZ
)
{
float3 cov1 = tex2D(covMap1, iTexCoord0).rgb;
float3 cov2 = tex2D(covMap2, iTexCoord0).rgb;
float3 cov3 = tex2D(covMap3, iTexCoord0).rgb;

iTexCoord0.x *= splatScaleX;
iTexCoord0.y *= splatScaleZ;

oColor = tex2D(splat1, iTexCoord0) * cov1.x
+ tex2D(splat2, iTexCoord0) * cov1.y
+ tex2D(splat3, iTexCoord0) * cov1.z
+ tex2D(splat4, iTexCoord0) * cov2.x
+ tex2D(splat5, iTexCoord0) * cov2.y
+ tex2D(splat6, iTexCoord0) * cov2.z
+ tex2D(splat7, iTexCoord0) * cov3.x
+ tex2D(splat8, iTexCoord0) * cov3.y
+ tex2D(splat9, iTexCoord0) * cov3.z;

}



mSplatMgr = new ET::SplattingManager("ETSplatting", "ET", 1024, 1024, 3);
mSplatMgr->setNumTextures(9);


Works fine, but currently leaves me with the problem my decal not showing up anymore...

tod

11-02-2008 20:10:53

So OK, I have used the generated image from SplattingManager::createBaseTexture() as a texture for the terrain, and it looks almost good. I see two possibilities next, and I will like your feedback:
1) I could increase the size of the texture so that it looks good, either that or use more texture for the terrain. I'm not sure if either of this decreases performance in a significant way.
2) I could use the texture for the terrain and on top of that use splatting for other things that need more detail. As I can see, the coverage map doesnt support transparency. Is there some easy way to add it?

Anyway, as I think this is going to take a long time for me to understand it, if anyone has the time and the inclination to answer some more stupid questions please contact me on Yahoo Messenger, id: todlesstod.
Thanks.

SongOfTheWeave

12-02-2008 04:55:08

So OK, I have used the generated image from SplattingManager::createBaseTexture() as a texture for the terrain, and it looks almost good. I see two possibilities next, and I will like your feedback:
1) I could increase the size of the texture so that it looks good, either that or use more texture for the terrain. I'm not sure if either of this decreases performance in a significant way.


createBaseTexture() is not the "intended" way to do splatting. Intended is in quotes because there are certainly applications for the base texture, such as creating a minimap, or using it instead of dynamic splatting during gameplay on low performance systems (though... now that I think of it, I've no idea how much perfomance that would buy you.)

The "intended" way to use the splatting manager is to do dynamic splatting all the time. The reason splatting is good is that it lets you use small images to cover a large terrain without simply monotonously tiling them. To generate a (very) large base texture map and apply that to the entire terrain sorta defeats that purpose unless you have a specific good reason to do it.

2) I could use the texture for the terrain and on top of that use splatting for other things that need more detail. As I can see, the coverage map doesnt support transparency. Is there some easy way to add it?

I'm not sure... if you are saying what you mean to be saying here.

The coverage map is never "shown" anywhere... it is possible to use the alpha (transparency) channel of the image to store another texture. Are you trying to have a portion of your terrain have no texture?

What I think is more likely is that you want a part of your terrain to be transparent. Just make a transparent image and splat that as normal. I haven't tried it, but I think it would work.

CABAListic

12-02-2008 07:41:37

createBaseTexture() is not the "intended" way to do splatting. Intended is in quotes because there are certainly applications for the base texture, such as creating a minimap, or using it instead of dynamic splatting during gameplay on low performance systems (though... now that I think of it, I've no idea how much perfomance that would buy you.)
You'd definitely get a performance boost due to only having a single texture without any shader calculations, even more so if quite a few splatting textures are involved. But the size of the texture is limited, you can't really go above 1024 or 2048 at most, therefore the visual quality will reduce.

@tod: Your 1) option has its limits, as stated. The higher the resolution, the more video RAM you'll be using which will fight any framerate gains you were getting. But 2) does not sound so great, either. With that approach, you'd effectively be using splatting again with all its performance implications - then forget about the base texture and just use splatting, that will at least give you a nicer visual quality ;)
In any case, you could just use one of the coverage channels for the base texture instead of a splatting texture. You'd have to change the shaders for this, though.

The only viable option would be to use splatting at short distances and switch to the base texture when the camera is further away (i. e. a LOD approach). But this is neither easy to do nor is it currently supported by ETM since apparently the terrain renderables must implement the material LOD switching, and I was not aware of that until recently.

Nauk

13-02-2008 02:28:40

@tod:

http://www.ogre3d.org/phpBB2addons/viewtopic.php?t=6402

Just add this as last pass to each technique in the ETTerrain.material file and point to your base texture or colormap.