考虑到以下情况,我想知道智能手机将如何打包2个纹理坐标以便在顶点着色器中快速使用:
我的问题是我自己并不熟悉浮点数的位布局,但我可以想象0.0f中只有1位需要翻转成为1.0f - 我只是不知道哪一个;只使用按位运算这应该是令人难以置信的快速(顺便说一下:与算术相比,像CPU一样,gpu的位数也更快吗?)。
答案 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;
}