PDA

View Full Version : Combining multiple textures



Kipt88
04-26-2010, 10:41 AM
Hello,
I need to combine 8 3D textures and could use your help.
I've tried to create a new texture by combining them using software but my program requires around 250 different combinations per source texture so I run out of memory (my program stopped after 260 Mb allocated memory).
So for my program to work I need to combine textures at runtime, I found out that you can combine textures with glTexEnv using GL_COMBINE_* and GL_INTERPOLATE, however I have no idea how to interpolate more than two textures using this method.
A third option I've considered is using GLSL, but since not all computers have 8 or more multitextures I prefer not to use GLSL to combine my textures.

Does anyone have an idea how to combine / interpolate 8 textures at runtime?

Alfonse Reinheart
04-26-2010, 11:11 AM
What is the function you want to apply to the textures?

Kipt88
04-27-2010, 05:32 AM
It's a kind of interpolation.

Each texel is an interpolation of 8 given textures, using this function.

(i = 1...8)
T(x, y, z) = (1 / s^3)SUM(|a_i * s - x||b_i * s - y||c_i * s - z|B_i(x,y,z)

where
T is the final texture
s is the size of all textures (all have the same and are cubes)
B_i is the i:th texture
|x| is the absolute value of x
a_i, b_i and c_i are constants that I use to simplify the function, they are (/ can be) defined as:

i|1 2 3 4 5 6 7 8
a|1 0 0 1 1 0 0 1
b|1 1 0 0 1 1 0 0
c|1 1 1 1 0 0 0 0

These constants are octants.
This is the 1D version of the function:

(i = 1..2)
T(x) = (1/s)SUM(|a_i*s - x|B_i(x)
= (1/s)( (s - x)B_1(x) + xB_2(x) )
= (1 - x/s)B_1(x) + (x/s)B_2(x)

This is a simple interpolation.

If you have trouble reading the function try writing it down on paper and you'll might see it clearer.

Ilian Dinev
04-27-2010, 06:45 AM
"not all computers have 8 or more multitextures" - that's a fixed-func limitation. A more realistic limitation with GLSL is 16 at minimum, afaik.

DmitryM
04-27-2010, 06:46 AM
There is a big chance I'm wrong here, but still:

You access the same texture coordinate in all textures as you write to, so the processing is sequential.
The idea is to work with your data as with vertex data instead of texture data. Steps to do it:

1) Read each 3d texture into PBO.
2) Specify 8 input generic vertex attributes from this 8 PBO's (or one merged).
3) Run a vertex processing program with Transform Feedback, writing the output to another buffer object.
4) Read the contents of this BO to the result 3d texture.

This may be even faster, because you are taking the sequential access pattern into account.

Kipt88
04-27-2010, 09:57 AM
"not all computers have 8 or more multitextures" - that's a fixed-func limitation. A more realistic limitation with GLSL is 16 at minimum, afaik. I have ATI Radeon HD 3600 Series and have GL_MAX_TEXTURE_UNITS 8.

Kipt88
04-27-2010, 10:02 AM
I'll check out PBO's, as long as I don't have to precalculate all textures I should be fine.

Alfonse Reinheart
04-27-2010, 10:40 AM
There is a big chance I'm wrong here, but still:

If his hardware can do all of that, then he can just sample from 8 textures in the fragment program.


I have ATI Radeon HD 3600 Series and have GL_MAX_TEXTURE_UNITS 8.

That's the enum for legacy fixed-function texture units. What you're looking for is GL_MAX_TEXTURE_IMAGE_UNITS.

DmitryM
04-27-2010, 11:28 AM
If the role of the program is pure processing, then the PBO conversion stages can be omitted by dealing directly with buffer objects. Then, there is only TF support that is required (GL 2.0+).

Still, I don't know the hardware not supporting 8 texture units. Just proposing an alternative...