0

I want to create a function that takes multiple textures and append them and tiles them next to each other. Example, if I had imgA, imgB, imgC I can get an texture like this:

A A B

C B B

B C A

Also image do not have to be the same size so I might get something like this:

AAB C

C B B

BAC C

Does anyone how I can do this in HLSL, what functions I should be looking at? Do you have any syntax example?

Thank you :)

EDIT: I am not quite satisfied with the answers yet, I will be exploring them more in depth, then coming back to this question

Daniel A. White
  • 187,200
  • 47
  • 362
  • 445
Joseph Azzam
  • 105
  • 1
  • 14

2 Answers2

1

Running loops in HLSL pixel shaders is not the best idea. It's probably easier to stream the vertices corresponding to the desired tiled texture.

First, you would want to create a texture atlas, i.e., a big texture which contains all the textures you want to compose. Then you render one quad (2 triangles) after another in the desired arrangement.

  • You can use n Draw calls: one quad at a time.

  • You can make one big vertex buffer with pre-computed or partially computed tile positions and use one Draw call.

  • Or you can do one DrawInstanced call. This is how tile-based maps are rendered in most games.


If you don't want to create a texture atlas, you could pass each of the base textures to a separate sampler and then map the texture coordinates to the appropriate sampler. However, this adds branching to the pixel shader which is also going to cost performance.

szym
  • 5,606
  • 28
  • 34
  • ok, thank you, the atlas concept looks interesting. do you recommend any tutorials? This is the first time I try to write a shader, anything would help – Joseph Azzam Aug 21 '16 at 11:24
  • 1
    Loop are not that bad anymore, and GPU are flexible enough to see most resources for there need, Bindless texture for example allow you to bind all the textures, regardless of there formats and size and pick the one you need inside HLSL, either from an indirection texture, vertex attributes, etc. But in the OP question, it does not gonna do any good, traditional solutions, cuting the screen in quads with vertices for each texture is the simplest. – galop1n Aug 22 '16 at 22:49
0

That question is little to broad, there is far to many ways to do what you describe. Some solutions could probably use a large uber shader and embedded most of the logic in the hlsl, but it does not seems right and complex for nothing. It would be more affordable to mix with some generated geometry for each portion of the screen.

There is likely to have absolutely no performance penalty from binding each texture separately and render quads to the correct locations, even or the weakest hardware.

galop1n
  • 8,573
  • 22
  • 36
  • interesting approach, so you're saying I don't have to do this in the shader, I can just do this using regular script, and just script the geometry itself. But wouldn't that increase the draw calls? – Joseph Azzam Aug 23 '16 at 16:14
  • How many draw calls do you think it would be ? Even if you have a thousand unique tile texture on screen, a thousand draw calls are not that bad, if you do it right and only a texture change in between and not a shader. You should first focus on getting something working, then optimize if there is perf concerns, using atlas or whatever. – galop1n Aug 23 '16 at 17:35