Dynamic multiple textures in HLSL

Hello !

I’m creating a 3d level editor, and I want it to load an unlimited number of textures.
So, foreach tiles of my terrain I set the tile’s texture to the shader, but the game goes realy slowly and the FPS goes down :frowning:

But, like I said in the topic’s title, I wonder if it’s possible to create an Texture2D array (and sampler) in the shader wich there gonna be initialized at the runtime.

I’ve seen Texture2DArray are compatible in DirectX 10-11 so in my HLSL compiles, but MonoGame doesn’t accept the Texture2DArray signature to the Effect.Parameters[…].SetValue(…).

Is there a better solution to avoid the calls to the shader ?

Thanks you :slight_smile:

Hi, in Direct3D 9 (no texture arrays) this problem was usually solved by batching all textures together into a texture atlas. (A Google search for “texture atlas” should bring up a lot of useful links that will get you started.)

You don’t need a massive amount of textures to do great-looking terrain. There are neat ways to blend between multiple textures (up to 4 in a single shader/object is a good number) so that you can get more variety than you can by simply drawing a single texture per tile.

Even without texture arrays, you can still group tiles to minimize the CPU time spent issuing draw calls to the GPU. Collect all the tiles that use any particular texture and draw them all in one draw. Even if you have 100 different textures, 100 draws aren’t really that many.


A texture atlas looks like a good solution i think.
And what you said is true DissidentDan, the problem is that my terrain works with tiles, and each tile can have 4 textures (one texture on each corner of the tile).

I’m gonna do some tests around the TextureAtlas, but that’s too bad that monogame doesn’t implement DirectX11 features ^^

Thanks for your answers :slight_smile:

I corrected a typo in my previous reply “that you can” -> “than you can”.

My approach would be to find all unique combinations of textures assigned to tiles, and do one draw call that would render all tiles that use that particular combination. You can easily render 4 textures at a time without needing atlases. You just have to have all tiles that render in the same draw call use the same 4 textures. But there’s not reason you can’t do what I just mentioned and issue multiple draw calls to cover all the used combinations. I don’t know what your game is like, I doubt you’ll have more than 100 such combinations, which is well within the range of acceptable draw call counts.