1
\$\begingroup\$

I went through the google I/O video but did not get exactly how to do it. If somebody could point me to a simple 3D texture implementation using webgl, it would be helpful.

i basically have a volume, a cube, i want to fill it up with pixel data, which comes from a stack of images along the x-y axis. How do i do that?

\$\endgroup\$
5
\$\begingroup\$

Here's the GLSL function slightly fixed from the Google I/O talk

  #define FILTER_LUT true

  vec4 sampleAs3DTexture(sampler2D tex, vec3 texCoord, float size) {
    float sliceSize = 1.0 / size;                  // space of 1 slice
    float slicePixelSize = sliceSize / size;       // space of 1 pixel
    float width = size - 1.0;
    float sliceInnerSize = slicePixelSize * width; // space of size pixels
    float zSlice0 = floor( texCoord.z * width);
    float zSlice1 = min( zSlice0 + 1.0, width);
    float xOffset = slicePixelSize * 0.5 + texCoord.x * sliceInnerSize;
    float yRange = (texCoord.y * width + 0.5) / size;
    float s0 = xOffset + (zSlice0 * sliceSize);

    #ifdef FILTER_LUT

      float s1 = xOffset + (zSlice1 * sliceSize);
      vec4 slice0Color = texture2D(tex, vec2(s0, yRange));
      vec4 slice1Color = texture2D(tex, vec2(s1, yRange));
      float zOffset = mod(texCoord.z * width, 1.0);
      return mix(slice0Color, slice1Color, zOffset);

    #else

      return texture2D(tex, vec2( s0, yRange));

    #endif
  }

The talk's code is hosted here.

If you want a 8x8x8 3D texture you'd make 64x8 texture and put each slice of the cube across the texture

[slice0][slice1][slice2]....[slice7]

Then make a sampler2D uniform in your shader and call

sampleAs3DTexture(yourSampler, your3DTexCoord, size)

where size the size of your cube (in the example size = 8)

NOTE: WebGL2 has built in support for 3D textures

\$\endgroup\$
  • \$\begingroup\$ thanks @gman for your answer! how is it possible to change the code, so that we can have a e.g. 8x8x5 texture instead? It seems that this doesn't work properly: ` vec4 sampleAs3DTexture(sampler2D tex, vec3 texCoord, float size, vec2 texDimensions) { float sliceSize = 1.0 / size; float slicePixelSize = sliceSize / texDimensions.x; float sliceInnerSize = slicePixelSize * (texDimensions.x - 1.0);` Or what does "space of size pixels" mean? \$\endgroup\$ – dforce Jan 16 '13 at 13:33
  • \$\begingroup\$ if you make your slices 8x5 so that your cube is 8x5x8 and your 2D version of that texture is width=8*8, height=5 it should just work. No Changes. \$\endgroup\$ – gman Jan 17 '13 at 19:23

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.