重要的是要知道的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);
这将上传包含3辆32位的花车和132种颜色的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);
与相应的着色器代码看起来像这样:
attribute vec3 aPosition;
attribute vec4 aColor;
void main() {
// Manipulate the position and color as needed
}
这种方式,你必须使用交错阵列的好处,这GPU喜欢使用,并且只需要跟踪一个缓冲区(奖金!),而且不会浪费每个颜色分量的完整浮动空间。如果你真的希望变小,你可以用短裤代替花车,但我过去的经验表明,使用短属性时桌面GPU不是非常快。
希望有帮助!
我不完全相信包装你描述的方式会更有效率。你以前如何暴露xyz/rgb数据? – Toji 2012-03-06 16:18:21