所以在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纹理中使用行主要顺序的效果? 想法?
提前致谢!
答案 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);
}
注意:上面的函数假设您希望在平面之间进行双线性过滤。如果你没有,你就可以简化这项功能。