如何最好地打包2个纹理坐标以进行快速顶点缓冲处理? (WebGL GPU浮动包装)

时间:2014-04-08 01:13:42

标签: floating-point glsl webgl shader bit-manipulation

考虑到以下情况,我想知道智能手机将如何打包2个纹理坐标以便在顶点着色器中快速使用:

  • 两个纹理坐标只能是1.0f或0.0f =>每个1位就够了
  • 我必须将这两个coords打包成一个GLByte(8位)属性变量;但是,如果其他用法仍有6位可用,那将是最好的

我的问题是我自己并不熟悉浮点数的位布局,但我可以想象0.0f中只有1位需要翻转成为1.0f - 我只是不知道哪一个;只使用按位运算这应该是令人难以置信的快速(顺便说一下:与算术相比,像CPU一样,gpu的位数也更快吗?)。

1 个答案:

答案 0 :(得分:0)

在顶点着色器中完成了这样的操作:

uv = fract(vertex.xy);
normal = fract(vertex.z);
gl_Position = mvp * vec4(floor(vertex), 1.0)

显然,在通过最大纹理分辨率存储到VBO之前,必须按比例放大顶点xyz,例如256x256:

vbo.push_back(vertex.mul_xyz_scalar(256.0).floor().add_xyz(uv.x, uv.y, normal));

因此,如果vertex.x是.00390625,则它变为1.低于1/256的位置是次正规(丢失,上面的楼层截断它)。已经假设uv在0-1范围内。如果你真的坚持,你可以乘以2而不是256,除0和1之外的任何东西都会丢失。

一句警告。如果您受内存带宽限制(许多顶点,简单着色器,通常是非常复杂的静态网格物体),此技术仅适用于 。否则,着色器中的额外floor()成本是不值得的,并且你最好不要存储紫外线和法线。

最后,所有顶点都必须像这样按比例缩放256(如果您使用不带有uv / n的不同着色器),或者通过mvp矩阵缩小256(这通常不会产生额外的开销,除非在不使用现有矩阵的情况下直接在着色器中直接完成。

Ninja编辑:这是"字节"的快速通用功能里面装有漂浮物。

/*
 * Packed with: (x*32768+y*128+z)/32768.0 where x and y are 0-255, z is 0-127.
 * This function returns x and y in 0-256, and z in 0-1 range, scale to 128 as needed.
 */
void unpack887(in float v, out float x, out float y, out float z)
{
  x = floor(v);
  float rem = (v - x) * 256.0;
  y = floor(rem);
  z = rem - y;
}