Multiple Textures Tiled Onto Single Mesh

Started by
2 comments, last by gulgi 18 years, 2 months ago
Can you help ? I'm working on putting multiple textures tiled onto a single mesh. The reason for this is I have 10km square terrain meshes that need to be overlaid by map rasters. Initially I downgraded the 4000x4000 images to 1024x1024 but the degredation was pretty awful, and now want to render 4 tiled quadrants of the raster tother on a single 10km mesh. (1024 being a common maximum tex size, and this isn't simulated landscape but real maps). Why not just reduce the mesh size ? Like most terrain stuff I made a design choice to "clamp" the edges of the mesh tiles during simplification to prevent tearing, and the "edge to non-edge" ratio of vertexes makes 10km nice and accurate, whereas a solution involving a 5km mesh had "too much edge" and oversimplified the centre. Thats where I am ; my problem is that I intended to render all four textures in a single pass by using four sets of Tex Coords on the mesh - which works fine in principle. I set the following (some not duplicated for brevity, sample of two of the four here) -- Start of code device.SamplerState[0].AddressU = TextureAddress.Border; device.SamplerState[0].AddressV = TextureAddress.Border; device.SamplerState[1].AddressU = TextureAddress.Border; device.SamplerState[1].AddressV = TextureAddress.Border; device.SamplerState[0].BorderColor = Color.Transparent; device.SamplerState[1].BorderColor = Color.Transparent; device.TextureState[0].ColorOperation = TextureOperation.Modulate; device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor; device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse; device.TextureState[0].AlphaOperation = TextureOperation.SelectArg1; device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor; device.TextureState[1].ColorOperation = TextureOperation.Modulate; device.TextureState[1].ColorArgument1 = TextureArgument.TextureColor ; device.TextureState[1].ColorArgument2 = TextureArgument.Diffuse; device.TextureState[1].AlphaOperation = TextureOperation.SelectArg1; device.TextureState[1].AlphaArgument1 = TextureArgument.TextureColor; device.SetTextureStageState(0,TextureStageStates.TextureCoordinateIndex,1); device.SetTexture(0,this.highResolutionTextures[0]); device.SetTextureStageState(1,TextureStageStates.TextureCoordinateIndex,2); device.SetTexture(1,this.highResolutionTextures[1]); -- then render mesh. -- End of code Unfortunately the outcome of this (which I understand conceptually) is that the border color of transparent is in effect overwriting the previous texture stage so I only ever see the last texture stage. The Color.Transparent overwrites the underlying texture stage. I think my understanding of how the Texture stage merges the previous Alpha value isn't correct (other areas of the app where multiple textures are overlaid work fine - its just that the 'border color' doesn't seem to be counted as part of the output from the stage ... or something). I cant see a way out of this, can anyone help ? How would you render more than one non-overlapping texture on a single mesh ? Thanks, Phillip
Advertisement
Hi..

In stage 1 you do modulate with textureColor and Diffuse.
In the remaining texturestages you need to modulate between "current" and texturecolor. Current holds the data from the last stage, and you don't want to lose that. :)

Good luck!
Gulgi,

Brilliant, thanks. Just the nudge I needed to get me there. For reference to the site, the correct sequence and settings for tiling multiple different textures on a single mesh (in my case quadrants) is;

-- Start of code
device.SamplerState[0].AddressU = TextureAddress.Border;
device.SamplerState[0].AddressV = TextureAddress.Border;
device.SamplerState[1].AddressU = TextureAddress.Border;
device.SamplerState[1].AddressV = TextureAddress.Border;
device.SamplerState[2].AddressU = TextureAddress.Border;
device.SamplerState[2].AddressV = TextureAddress.Border;
device.SamplerState[3].AddressU = TextureAddress.Border;
device.SamplerState[3].AddressV = TextureAddress.Border;

device.SamplerState[0].BorderColor = Color.Transparent;
device.SamplerState[1].BorderColor = Color.Transparent;
device.SamplerState[2].BorderColor = Color.Transparent;
device.SamplerState[3].BorderColor = Color.Transparent;

device.TextureState[0].ColorOperation = TextureOperation.Modulate;
device.TextureState[0].ColorArgument1 = TextureArgument.TextureColor;
device.TextureState[0].ColorArgument2 = TextureArgument.Diffuse;
device.TextureState[0].AlphaOperation = TextureOperation.SelectArg1;
device.TextureState[0].AlphaArgument1 = TextureArgument.TextureColor;

device.TextureState[1].ColorOperation = TextureOperation.Modulate;
device.TextureState[1].ColorArgument1 = TextureArgument.Current ;
device.TextureState[1].ColorArgument2 = TextureArgument.TextureColor;
device.TextureState[1].AlphaOperation = TextureOperation.SelectArg1;
device.TextureState[1].AlphaArgument1 = TextureArgument.Diffuse;

device.TextureState[2].ColorOperation = TextureOperation.Modulate;
device.TextureState[2].ColorArgument1 = TextureArgument.Current ;
device.TextureState[2].ColorArgument2 = TextureArgument.TextureColor;
device.TextureState[2].AlphaOperation = TextureOperation.SelectArg1;
device.TextureState[2].AlphaArgument1 = TextureArgument.Diffuse;

device.TextureState[3].ColorOperation = TextureOperation.Modulate;
device.TextureState[3].ColorArgument1 = TextureArgument.Current ;
device.TextureState[3].ColorArgument2 = TextureArgument.TextureColor;
device.TextureState[3].AlphaOperation = TextureOperation.SelectArg1;
device.TextureState[3].AlphaArgument1 = TextureArgument.Diffuse;

// Note the first TU/TV pair in my FVF refer to another texture stage.
device.SetTextureStageState(0,TextureStageStates.TextureCoordinateIndex,1);
device.SetTexture(0,this.highResolutionTextures[0]);
device.SetTextureStageState(1,TextureStageStates.TextureCoordinateIndex,2);
device.SetTexture(1,this.highResolutionTextures[1]);
device.SetTextureStageState(2,TextureStageStates.TextureCoordinateIndex,3);
device.SetTexture(2,this.highResolutionTextures[3]);
device.SetTextureStageState(3,TextureStageStates.TextureCoordinateIndex,4);
device.SetTexture(3,this.highResolutionTextures[2]);

-- End of code

Just one further question ; is setting the SampleState an expensive operation on a per-frame basis (I've bunched all my code up in the above sample for clarify), or should I set it only once in the app ?

Phillip
Glad I could help. :)

I don't know much about how low stuff takes in D3D (I'm an OpenGL person ;]), but the usual rule is to use as few statechanges you can get away with.
But then, the only ones I know are _slow_ is changing textures and shaders, so setting some sampler state shouldn't effect anything.

And if you are concerned, time the code with and without those calls and see if there is any difference. :)

Good luck!

This topic is closed to new replies.

Advertisement