So… what is a Texture3D anyway?

I thought it’s already a three-dimensional block of voxels that can be sent to the GPU and rendered directly, but that’s not what’s happening in TestTexture3D it seems:

  • TestTexture3D is showing a sphere, and I don’t quite understand how the texture block is combined with the sphere geometry
  • going inside the sphere, I don’t see a thing - I’d have expected to see whatever inside voxel is in front of me

I’m probably grossly misunderstanding something there, but I’m not sure how to proceed to clear that up.
So, anything to put me on the right track is mightily appreciated.

You’ve probably already seen stuff like this but maybe not… and maybe it answers the question:

1 Like

The test case example is quite dumb yes, it’s just here to prove that it’s working :stuck_out_tongue:

Basically it just maps the texture on the sphere with x,y,z as texture coordinates.
See texture 3D as 2d images stacked together. the z coordinate being the “number” of textures.
That’s looks like a textureArray, but the big difference is that you can fetch non integer Z coordinates and the result will be interpolated between 2 images.
For example let say you have a texture3D with 10 “slices”, fetching z=8.5 will return the interpolation between slice 8 and 9.

1 Like

Thanks for the link, I hadn’t seen that yet. I found it hard to find links that were useful, most either just repeated what I knew or were descriptions of readymade volumetric rendering engines.
A night’s sleep has also helped me sort out things for a bit :slight_smile:
(Oh, and I mistook the UV stuff in the test case for normals instead of texture-local coordinates. Confusion can be hilarious in hindsight…)

To answer my question: Seems like 3D textures aren’t 3D bitmaps that you can tell the GPU to draw for you, they’re just volumetric data and the shader needs to interpret them. D’oh.

I hadn’t noticed the interpolation aspect though. Now the various “sample the texture” mentions in the descriptions start to make sense.
I take it that it will interpolate not just Z but X and Y, too? That’s sweet.
Hm… since I’ll want color right to the border of the texture, I’ll need to avoid edge artifacts, so I’ll be playing with GL_CLAMP_TO_EDGE. Or increase the texture size by 1 in each direction, offset it by 0.5, and don’t sample the edge areas.
Too many options to explore :frowning:

Hm. looks like there’s a lot of per-GPU variation what will work best. Sometimes even per-driver. And 3D textures are already performance sensitive. And sending loop indexes as uniforms doesn’t work for all cases either. So whatever I do, if it performs on my machine that doesn’t tell me if it will work on anybody else’s. (Seems like you need a hardware zoo if you do performance-sensitive stuff in 3D.)

Oh my god. I feel more hairs turning grey.

Yeah, general compatibility is something we have to postpone or reject a lot of things for… But generally one can say if it works properly on a Mac then it works on all other machines :wink: Apples OpenGL stack is very anal about spec conformity so its a good testing ground. It even flat out rejects multiplications where the definition of one float is ambivalent, e.g. (float)x * 1 gets rejected as a multiplication of int and float.

Heh. I’ll buy that hardware zoo once I get filthy rich with my game.
Except I won’t need it anymore then. And I probably won’t get filthy rich.
Ah well, you can’t have everything :slight_smile:

Yeah, the texture may be 3d but it’s still a texture, not a 3d object. In the same way that a 2d texture is mapped onto a geometry the 3d texture needs to somehow be mapped onto an object to display.

To get some of the behaviour you want you could try a billboarded quad and then use world co-ordinates as texture co-ordinates, you should then be able to see “inside” the texture by flying through it.

Actually I’ll be doing transparent voxels :slight_smile:
Which means it’s probably more efficient to have a single Box with a 3D texture attached, and have the shader sample the texture along the viewing axis.

That should work so long as you don’t want to view from inside the box :slight_smile: