Texture2D to Texture3D
Asked Answered
S

3

1

I would like to know how can I create a Texture3D from a Texture2D.

enter image description here

I've found some good examples : Unity 4 - 3D Textures (Volumes) or Unity - 3D Textures or Color Correction Lookup Texture

int     dim = tex2D.height;
Color[] c2D = tex2D.GetPixels();
Color[] c3D = new Color[c2D.Length];
for (int x = 0; x < dim; ++x)
{
    for (int y = 0; y < dim; ++y)
    {
        for (int z = 0; z < dim; ++z)
        {
            int y_ = dim - y - 1;
            c3D[x + (y * dim) + (z * dim * dim)] = c2D[z * dim + x + y_ * dim * dim];
        }
    }
}

But this only works when you have

Texture2D.height= Mathf.FloorToInt(Mathf.Sqrt(Texture2D.width))

or if

Depth = Width = Height

How can I extract the values when the depth is not equal to the width or the height ? It seems simple but I am missing something...

Thank you very much.

Selective answered 10/5, 2014 at 14:24 Comment(2)
How do you want to distribute the pixels over the 3d texture? Do the textures have equal width and/or height? Would it be sufficient to simply specify c2D as the 3d texture's data? This should wrap the pixels automatically somehow.Ekaterinoslav
Bad formating... You can look at answers.Selective
E
2

You can split the texture as follows:

//Iterate the result
for(int z = 0; z < depth; ++z)
    for(int y = 0; y < height; ++y)
        for(int x = 0; x < width; ++x)
            c3D[x + y * width + z * width * height]
              = c2D[x + y * width * depth + z * width]

You can get to this index formula as follows:

Advancing by 1 in the x-direction results in an increment by 1 (just the next pixel).

Advancing by 1 in the y-direction results in an increment by depth * width (skip 4 images with the according width).

Advancing by 1 in the z-direction results in an increment by width (skip one image row).

Or if you prefer the other direction:

//Iterate the original image
for(int y = 0; y < height; ++y)
    for(int x = 0; x < width * depth; ++x)
         c3D[(x % width) + y * width + (x / width) * width * height] = c2D[x + y * width * depth];
Ekaterinoslav answered 11/5, 2014 at 8:22 Comment(3)
Thank you very much. I don't have bad textures now.Selective
This looks like basically the same solution I posted a day earlier, only less efficient.Vadim
@RetoKoradi yeah, you're right. I haven't noticed that there was another answer. Sorry for that. But I assume that a C# solution was desired. Whatsoever, you have my up-vote.Ekaterinoslav
S
1

Unfortunately, there's not much documentation about the 3DTexture. I've tried to simply use the c2D as the Texture's data but it doesn't give an appropriate result.

For the moment I tried this which gives better result but I don't know of it's correct.

for (int x = 0; x < width; ++x)
{
    for (int y = 0; y < height; ++y)
    {
        for (int z = 0; z < depth; ++z)
        {
            int y_ = height - y - 1;
            c3D[x + (y * height) + (z * height * depth)] = c2D[z * height + x + y_ * height * depth];
        }
    }
}
Selective answered 10/5, 2014 at 15:10 Comment(4)
If x refers to height and y refers to depth then this may be correct. Otherwise it should be c3D[x + y * width + z * width * height] = c2D[x + z * width + y * width * height].Ekaterinoslav
Thank you, for me and a lot of people I think, x refers to the width, y to the height and z to the depth. I am a bit confused.Selective
I just had a closer look at your texture. Do you want to split the width into four parts and distribute those along the z-axis? So depth=4?Ekaterinoslav
Yes, this is exactly this. The four parts are distrubuted along the depth (4)Selective
V
0

From your picture, it looks like you have the planes of the 3D texture you want side by side? So you want a 3D texture with dimensions (width, height, depth) from a 2D texture with (width * depth, height)? You should be able to do this with something like this:

for (int z = 0; z < depth; ++z)
{
    for (int y = 0; y < height; ++y)
    {
        memcpy(c3D + (z * height + y) * width, c2D + (y * depth + z) * width, width * sizeof(Color));
    }
}
Vadim answered 10/5, 2014 at 17:17 Comment(1)
The aim is to distribute the four parts (width / 4) alors the depth.Selective

© 2022 - 2024 — McMap. All rights reserved.