In my project I need to blend some textures to use the final result as material.map in the mesh. Now I have two implementations:
With shaders: I create a shader that takes multiple textures as uniform and I make the blending in the fragment shader. The problem here is that I can’t use >10 textures because the Max Texture Image Units is 16 and there are some slots used by other maps.
With Canvas: First, I draw the original texture in the canvas and then I draw the other textures in the same canvas. I use the final result from the canvas as the texture for the mesh. The problem here is that now I’m using KTX textures (they have a lot of benefits). I’m trying to draw KTX textures on a canvas, but I don’t know how do it. Even I get it, this approach is not good because the final result from the canvas is not a compressed texture and it will take more GPU memory.
Is there any way to draw compressed texture in a canvas?
Is there any way to get a compressed texture from canvas?
Right now I’m blocked, any suggestions will be greatly appreciated!
You can still use shaders to blend any number of textures using multiple passes.
Lets say if you have 4 textures (T1, T2, T3, T4, T5) to blend and get
T = ( T1 + T2 + T3 + T4 + T5 ) / 4
Instead of doing it at once you can blend only 2 at a time and use that result.
A = ( T1 + T2 ) / 2
B = ( 2 * A + T3 ) / 3
C = ( 3 * B + T4 ) / 4
T = ( 4 * C + T5 ) / 5
Here each line is a single render pass and A,B,C would be temporary render targets, ideally, you only need a maximum of 2 of them, as at the 3rd pass A can be used again instead of C and B again at the next stage.
This would work for any number of textures (not just 5).
But if I draw on temporary render target the result will be a uncompressed texture, so I will lose the benefits of use ktx format.
Compressing a texture is a slow process, and you cannot generate a compressed texture by directly blending, it will have to be done again. You can probably use libktx to convert from a render target to ktx, save and use that later.
Memory-wise, if you are using 10 textures at once, they will be all be stored in memory at the same time vs just one render target, so it would in most cases need less memory, as you can dispose the rest after blending.
Plus, texture fetching is performance-intensive in the shader, so if you are doing 10 fetches, it would be slower than 1.