[编辑 - 一个问题几乎修复,改变了问题以反映它]
我正在研究Chrome中的点云webGL项目,它一次显示数百万个点.
为了使之更有效率,我已经试过包装我的数据 - 6辆XYZ和RGB花车 - 成两个64位整数(XY&zrgb),并计划解压它们在着色器.
我正在使用Chrome进行开发,而且,即使使用Canary,webkit也不支持任何类型的64位阵列类型.另外,Firefox确实支持64位阵列,但我仍然遇到错误.
这一行出现了问题:
gl.bufferData(gl.ARRAY_BUFFER, new Float64Array(data.xy), gl.DYNAMIC_DRAW);
Run Code Online (Sandbox Code Playgroud)
在Chrome中我得到的ArrayBufferView不是一个足够小的正整数,在FF中我得到'无效参数'.
所以我的问题是,有没有办法将64位数字发送到着色器,最好是使用Chrome,如果没有,在FF?
包装这样的数据是个好主意吗?有小费吗?!
谢谢,
约翰
重要的是要知道WebGL实际上并不关心TypedArray您提供它的格式.无论你给它什么,它都会将它视为不透明的二进制缓冲区.重要的是你如何设置你vertexAttribPointer的.这允许一些非常方便的来回移动数据的方法.例如:我经常从二进制文件中读取Uint8Array并将其作为缓冲区数据提供,但将其绑定为浮点数和整数.
TypedArrays还具有很好的能力,可以作为其他数组类型的视图,这使得混合类型变得容易(只要你没有对齐问题).在您的具体情况下,我建议做这样的事情:
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);
Run Code Online (Sandbox Code Playgroud)
这将上传一个紧凑的顶点缓冲区,其中包含3个32位浮点数和1个32位颜色到GPU.不像你提出的64位整数那么小,但GPU可能会更好地使用它.绑定它以便稍后渲染时,你会这样做:
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);
Run Code Online (Sandbox Code Playgroud)
使用相应的着色器代码如下所示:
attribute vec3 aPosition;
attribute vec4 aColor;
void main() {
// Manipulate the position and color as needed
}
Run Code Online (Sandbox Code Playgroud)
通过这种方式,您可以使用GPU喜欢使用的交错数组,并且只需跟踪单个缓冲区(奖励!),而且您不会为每个颜色组件使用完整浮动浪费空间.如果你真的想要变小,你可以使用短裤而不是花车作为位置,但我过去的经验表明桌面GPU在使用短属性时并不是非常快.
希望这有帮助!
| 归档时间: |
|
| 查看次数: |
1558 次 |
| 最近记录: |