[编辑 - 一个问题几乎已解决,更改了问题以反射(reflect)它]
我正在 Chrome 中开发一个点云 webGL 项目,该项目一次显示数百万个点。
为了提高效率,我尝试将数据(6 个 xyz 和 rgb 浮点)打包为两个 64 位整数(xy 和 zrgb),并计划在着色器中将它们解包。
我正在 Chrome 中进行开发,但事实证明,webkit 不支持任何类型的 64 位数组类型...即使使用 Canary 也是如此。另外,Firefox 确实支持 64 位数组,但我仍然收到错误。
此行出现问题:
gl.bufferData(gl.ARRAY_BUFFER, new Float64Array(data.xy), gl.DYNAMIC_DRAW);
在 Chrome 中,我得到 ArrayBufferView 不是一个足够小的正整数,在 FF 中,我得到“无效参数”。
所以我的问题是,有没有办法将 64 位数字发送到着色器,最好使用 Chrome,如果没有,则在 FF 中?
另外,像这样打包数据是个好主意吗?有什么建议吗?!
谢谢
约翰
最佳答案
重要的是要知道 WebGL 实际上根本不关心您提供的 TypedArray
的格式。无论你给它什么,它都会将其视为不透明的二进制缓冲区。重要的是如何设置 vertexAttribPointer
。这允许使用一些非常方便的方法来来回移动数据。例如:我经常从二进制文件中读取 Uint8Array 并将其作为缓冲区数据提供,但将其绑定(bind)为 float 和整数。
TypedArrays 还具有充当其他数组类型的 View 的出色能力,这使得混合类型变得很容易(只要没有对齐问题)。根据您的具体情况,我建议这样做:
var floatBuffer = new Float32Array(verts.length * 4);
var byteBuffer = new Uint8Array(floatBuffer); // View the floatBuffer as bytes
for(i = 0; i < verts.length; ++i) {
floatBuffer[i * 4 + 0] = verts.x;
floatBuffer[i * 4 + 1] = verts.y;
floatBuffer[i * 4 + 2] = verts.z;
// RGBA values expected as 0-255
byteBuffer[i * 16 + 12] = verts.r;
byteBuffer[i * 16 + 13] = verts.g;
byteBuffer[i * 16 + 14] = verts.b;
byteBuffer[i * 16 + 15] = verts.a;
}
var vertexBuffer = gl.createBuffer();
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, floatBuffer, gl.STATIC_DRAW);
这会将包含 3 个 32 位 float 和 1 个 32 位颜色的紧密封装顶点缓冲区上传到 GPU。不像您建议的一对 64 位整数那么小,但 GPU 可能会更好地处理它。当稍后绑定(bind)它进行渲染时,您可以这样做:
gl.bindBuffer(gl.ARRAY_BUFFER, vertexBuffer);
gl.vertexAttribPointer(attributes.aPosition, 3, gl.FLOAT, false, 16, 0);
gl.vertexAttribPointer(attributes.aColor, 4, gl.UNSIGNED_BYTE, false, 16, 12);
相应的着色器代码如下所示:
attribute vec3 aPosition;
attribute vec4 aColor;
void main() {
// Manipulate the position and color as needed
}
通过这种方式,您可以享受使用交错数组的好处,GPU 喜欢使用交错数组,并且只需跟踪单个缓冲区(好处!),而且您不会为每个颜色分量使用完整的浮点来浪费空间。如果你真的想变小,你可以在位置上使用 Shorts 而不是 float,但我过去的经验表明,使用 Short 属性时,桌面 GPU 的速度并不是非常快。
希望有帮助!
关于webkit - 在WebGL中打包数据: float64/int64Arrays in Chrome,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9583426/