由二维阵列表示的三维阵列 -

时间:2013-11-12 20:47:24

标签: arrays multidimensional-array 3d textures webgl

所以在WebGL中,我可以存储最多2维的纹理 - 并使用texture2D(无论如何)在着色器中读取它;

如果我想存储一个三维纹理,以便我可以在着色器上读取三维数据,我该怎么做?

以下是我的想法 - 我想知道我是否正确接近它:

在Javascript中:

var info = [];

for (var x = 0; x < 1; x+=.1) {
     for (var y = 0; y < 1; y+=.1) {
          for (var z = 0; z < 1; z+=.1) {

               info.push (x*y*z); 
               info.push(0);
               info.push(0);
               info.push(0);

          }
     }
}

//bind texture here- whatever

gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, 10, 100, 0,
                  gl.RGBA, gl.FLOAT, data_on_shader);

//other texture stuff

在着色器上:

uniform sampler data_on_shader;
x= texture.r//
y = texture.g//
z = texture.b//

xfixed = floor(x*10.)/10. + .5;
yfixed = floor(y*10.)/10. + .5;
zfixed = floor(z*10.)/10. + .5;

float data_received = texture2D(data_on_shader, vec2(xfixed, yfixed*10. + zfixed)).r;

在2d纹理中使用行主要顺序的效果? 想法?

提前致谢!

1 个答案:

答案 0 :(得分:3)

您可以通过将3d纹理的每个平面存储在2d纹理中来模拟3d纹理

然后像这样的函数可以让你将它用作3d纹理

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 sliceInnerSize = slicePixelSize * (size - 1.0); // space of size pixels
    float zSlice0 = min(floor(texCoord.z * size), size - 1.0);
    float zSlice1 = min(zSlice0 + 1.0, size - 1.0);
    float xOffset = slicePixelSize * 0.5 + texCoord.x * sliceInnerSize;
    float s0 = xOffset + (zSlice0 * sliceSize);
    float s1 = xOffset + (zSlice1 * sliceSize);
    vec4 slice0Color = texture2D(tex, vec2(s0, texCoord.y));
    vec4 slice1Color = texture2D(tex, vec2(s1, texCoord.y));
    float zOffset = mod(texCoord.z * size, 1.0);
    return mix(slice0Color, slice1Color, zOffset);
 }

如果您的3d纹理是8x8x8,那么您将制作一个64x8的2D纹理,并将3d纹理的每个平面放在您的2D纹理中。然后,知道原来是8x8x8,您将8.0的尺寸传递给sampleAs3DTexture

precision mediump float;
uniform sampler2D u_my3DTexture;
varying vec3 v_texCoord;

...

#define CUBE_SIZE 8.0

void main() {
  gl_FragColor = sampleAs3DTexture(u_my3DTexture, v_texCoord, CUBE_SIZE);
}

注意:上面的函数假设您希望在平面之间进行双线性过滤。如果你没有,你就可以简化这项功能。

a video explanation of this code here来自this sample